Android在列表视图中拖放、单击和滚动

Android在列表视图中拖放、单击和滚动,android,android-layout,android-fragments,android-listview,ontouchlistener,Android,Android Layout,Android Fragments,Android Listview,Ontouchlistener,所以我有一个这样的布局: 我现在使用的是Listview,每行有一个Imageview和两个TextView 我希望能够在此页面上完成3件事: 单击一行(或者仅仅单击该行中的Imageview对我也适用)会让我看到另一个片段 可以拖动每个Listview行中的图像。它使用DragShadowBuilder,因此可以检测是否将其放入底部的深灰色区域 您可以在Listview中上下滚动以查看当前溢出的其他项目 可以想象,这三种情况很难捕捉,因为很难区分这三种情况(功能重叠的bc) 我更喜欢而不是使

所以我有一个这样的布局:

我现在使用的是Listview,每行有一个Imageview和两个TextView

我希望能够在此页面上完成3件事:

  • 单击一行(或者仅仅单击该行中的Imageview对我也适用)会让我看到另一个片段
  • 可以拖动每个Listview行中的图像。它使用DragShadowBuilder,因此可以检测是否将其放入底部的深灰色区域
  • 您可以在Listview中上下滚动以查看当前溢出的其他项目
  • 可以想象,这三种情况很难捕捉,因为很难区分这三种情况(功能重叠的bc)

    我更喜欢而不是使用onItemLongClickListener来进行拖放bc用户通常不会想长时间按住手指来开始拖放

    关于如何实现这一点以捕获所有三个用例,有什么建议吗?实际上,它可以被认为是两个用例,因为如果我将一个图像放回其原始容器中,它可以算作对我的点击。最复杂的部分是如何通过上下滚动Listview使其工作

    提前谢谢你的帮助

    p、 整个视图呈现在一个片段中,单击一个视图或成功地将一个视图放入灰色区域将打开一个单独的片段。

    /**
    
     /**
     * Call this from a drag source view.
     */
    @SuppressLint("NewApi")
    public boolean onTouchEvent(MotionEvent ev) {
        if (!mDragging) {
            return false;
        }
    
        final int action = ev.getAction();
        final int screenX = clamp((int)ev.getRawX(), 0, mDisplayMetrics.widthPixels);
        final int screenY = clamp((int)ev.getRawY(), 0, mDisplayMetrics.heightPixels);
    
        switch (action) {
        case MotionEvent.ACTION_DOWN:
            // Remember where the motion event started
            mMotionDownX = screenX;
            mMotionDownY = screenY;
            break;
        case MotionEvent.ACTION_MOVE:
            //Set background color of remove comment box layout
            if(((int)ev.getY() <= 50))
                ImageEditingActivityNew.rl_remove.setBackgroundColor(Color.RED);
            else
                ImageEditingActivityNew.rl_remove.setBackgroundColor(Color.TRANSPARENT);
    
            // Update the drag view.  Don't use the clamped pos here so the dragging looks
            // like it goes off screen a little, intead of bumping up against the edge.
            mDragView.move((int)ev.getRawX(), (int)ev.getRawY());
    
            // Drop on someone?
            final int[] coordinates = mCoordinatesTemp;
            DropTarget dropTarget = findDropTarget(screenX, screenY, coordinates);
            if (dropTarget != null) {
                if (mLastDropTarget == dropTarget) {
                    dropTarget.onDragOver(mDragSource, coordinates[0], coordinates[1],(int) mTouchOffsetX, (int) mTouchOffsetY, mDragView, mDragInfo);
                } else {
                    if (mLastDropTarget != null) {
                        mLastDropTarget.onDragExit(mDragSource, coordinates[0], coordinates[1],(int) mTouchOffsetX, (int) mTouchOffsetY, mDragView, mDragInfo);
                    }
                    dropTarget.onDragEnter(mDragSource, coordinates[0], coordinates[1],
                        (int) mTouchOffsetX, (int) mTouchOffsetY, mDragView, mDragInfo);
                }
            } else {
                if (mLastDropTarget != null) {
                    mLastDropTarget.onDragExit(mDragSource, coordinates[0], coordinates[1],
                        (int) mTouchOffsetX, (int) mTouchOffsetY, mDragView, mDragInfo);
                }
            }
            mLastDropTarget = dropTarget;
    
    
            /* The original Launcher activity supports a delete region and scrolling.
               It is not needed in this example.
    
            // Scroll, maybe, but not if we're in the delete region.
            boolean inDeleteRegion = false;
            if (mDeleteRegion != null) {
                inDeleteRegion = mDeleteRegion.contains(screenX, screenY);
            }
            //Log.d(TAG, "inDeleteRegion=" + inDeleteRegion + " screenX=" + screenX
            //        + " mScrollZone=" + mScrollZone);
            if (!inDeleteRegion && screenX < mScrollZone) {
                if (mScrollState == SCROLL_OUTSIDE_ZONE) {
                    mScrollState = SCROLL_WAITING_IN_ZONE;
                    mScrollRunnable.setDirection(SCROLL_LEFT);
                    mHandler.postDelayed(mScrollRunnable, SCROLL_DELAY);
                }
            } else if (!inDeleteRegion && screenX > scrollView.getWidth() - mScrollZone) {
                if (mScrollState == SCROLL_OUTSIDE_ZONE) {
                    mScrollState = SCROLL_WAITING_IN_ZONE;
                    mScrollRunnable.setDirection(SCROLL_RIGHT);
                    mHandler.postDelayed(mScrollRunnable, SCROLL_DELAY);
                }
            } else {
                if (mScrollState == SCROLL_WAITING_IN_ZONE) {
                    mScrollState = SCROLL_OUTSIDE_ZONE;
                    mScrollRunnable.setDirection(SCROLL_RIGHT);
                    mHandler.removeCallbacks(mScrollRunnable);
                }
            }
            */
            break;
        case MotionEvent.ACTION_UP:
            //When touch up then remove comment box
    
            if(((int)ev.getY() <= 50)) {
                ImageEditingActivity.rl_imageEdit_comment.removeAllViews();
                ImageEditingActivity.rl_imageEdit_comment.invalidate();
                //ImageEditingActivity.mDragLayer.removeView(ImageEditingActivity.rl_imageEdit_comment);
                ImageEditingActivity.addComment = true;
                ImageEditingActivity.changeIconBackground("Remove");
                ImageEditingActivity.editParam.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
            }
    
            if (mDragging) {
                drop(screenX, screenY);
            }
    
            endDrag();
            break;
        case MotionEvent.ACTION_CANCEL:
            cancelDrag();
        }
    
        return true;
    }
    
    *从拖动源代码视图中调用此函数。 */ @SuppressLint(“新API”) 公共事件(MotionEvent ev){ 如果(!mDragging){ 返回false; } final int action=ev.getAction(); final int screenX=clamp((int)ev.getRawX(),0,mDisplayMetrics.widthPixels); final int screenY=clamp((int)ev.getRawY(),0,mDisplayMetrics.heightPixels); 开关(动作){ case MotionEvent.ACTION\u DOWN: //还记得运动事件从哪里开始吗 mMotionDownX=screenX; mMotionDownY=有屏幕; 打破 case MotionEvent.ACTION\u移动: //设置删除注释框布局的背景色 if(((int)ev.getY()scrollView.getWidth()-mScrollZone){ 如果(mScrollState==滚动到\u区域外){ mScrollState=滚动\u区域中的\u等待\u; mScrollRunnable.setDirection(向右滚动); mHandler.postDelayed(mScrollRunnable,SCROLL\u DELAY); } }否则{ if(mScrollState==滚动区域中的等待){ mScrollState=在区域外滚动; mScrollRunnable.setDirection(向右滚动); mHandler.removeCallbacks(mScrollRunnable); } } */ 打破 case MotionEvent.ACTION\u UP: //修补时,移除注释框
    如果(((int)ev.getY()而不是长时间按住,您可以使用fling/swipe手势。您可以覆盖的onFling方法并基于阈值检测fling。

    您的需求冲突。我将在您的情况下做下一件事:

  • 只有长按才能拖动行(然后我将使用阴影拖动) 此外,我会这样做,下降的看法,只有出现在长按发生

  • override
    单击
    ImageView
    onclick
    方法,这样您就可以单击它,然后调用片段进行展开

  • 现在,由于您没有覆盖该行上的任何
    onTouchListeners
    onClick
    ,因此只要不单击图片,您就可以自由滚动

  • 嘿,帕特尔,这看起来很有希望。你介意写一些关于代码中发生了什么的解释吗?我看不出与我所要求的有直接的联系。谢谢!你应该获得屏幕的最大位置,并且在移动放置条件下,你的拖拽视图处于最大位置,然后放下图像。不过,我预见的唯一问题是管理不同的onFling和onScroll之间的冲突。我希望能够让用户缓慢/快速地在listview上下滚动。但我也希望他们使用DragShadowBuilder拖动每个listview行中的图像。我可以使用SimpleOnGestureListener解决此问题吗?您有相互冲突的要求,但仍然可以使用dragshadow builder al进行尝试放纵地怒吼。