【问题标题】:Auto-moving image on drag listener拖动侦听器上的自动移动图像
【发布时间】:2015-08-03 08:26:40
【问题描述】:

我在我的应用程序中为ImageView 设置了一个拖动侦听器,但是当我单击它时,我不希望它根据我按下的位置将图像居中。它这样做:

https://gfycat.com/ConstantDisguisedKudu

基本上,如果我按下图像的bottom right,它会将我按下的位置设为central point,并将图像的center point 移动到该确切位置。但我不希望它那样做。如果我按下 bottom right ,它不应该自动移动,我可以从那个点拖动图像。我认为不需要任何代码,但以防万一:

@Override
public boolean onDrag(View v, DragEvent event) {
    switch (event.getAction()) {
        // Signal for the start of drag and drop operation
        case DragEvent.ACTION_DRAG_STARTED: {
            // do nothing
            break;
        }
        // The drag point has entered the bounding box of the View
        case DragEvent.ACTION_DRAG_ENTERED: {
            // do nothing
            break;
        }
        // The user has moved the drag shadow outside the bounding box of the view
        case DragEvent.ACTION_DRAG_EXITED: {
            // do nothing
            break;
        }
        // Drag shadow has been released, the drag point is within the bounding box of the view
        case DragEvent.ACTION_DROP: {
            // Get the image and its position
            ImageView view = (ImageView) event.getLocalState();
            int position = (int) view.getTag(R.id.piece_position);

            /**
             * If it is dropped on the left pane, remove it from its parent and also
             * remove the bitmap at the position and notify the adapter.
             * Add it to the left pane and set the position.
             */
            if (v == puzzlePane) {
                ViewGroup viewgroup = (ViewGroup) view.getParent();
                viewgroup.removeView(view);

                if (position != -1) {
                    pieces.remove(position);
                    mAdapter.notifyDataSetChanged();
                }

                FrameLayout containView = (FrameLayout) v;
                containView.addView(view);
                view.setVisibility(View.VISIBLE);
                view.setTag(R.id.piece_state, "left");
                view.setTag(R.id.piece_position, -1);
                view.setOnLongClickListener(null);
                view.setOnTouchListener(mAdapter);
            } else {
                view.setVisibility(View.VISIBLE);
                view.setTag(R.id.piece_state, "right");
                view.setOnTouchListener(null);
                view.setOnLongClickListener(mAdapter);
            }

            Log.d(MyDragListener.class.getSimpleName(), view.getTag(R.id.piece_state) + "");

            view.setX(event.getX() - (view.getWidth() / 2));
            view.setY(event.getY() - (view.getHeight() / 2));

            break;
        }
        // The drag and drop operation has concluded
        case DragEvent.ACTION_DRAG_ENDED: {
            // do nothing
            break;
        }
    }
    return true;
}

【问题讨论】:

    标签: android drag-and-drop onclicklistener drag ontouchlistener


    【解决方案1】:

    您需要扩展 View.DragShadowBuilder ,并发送您的手指相对于 continer 的位置。类似的东西:

    //where you trigger the dragging
    View yourImage; //
    
    yourImage.setOnTouchListener(new OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            final ClipData dragData = new ClipData("label", new String[]{ClipDescription.MIMETYPE_TEXT_PLAIN}, null);
            startDrag(dragData,  // the data to be dragged
                    new MyDragShadowBuilder(v, event.getX(), event.getY()), // the drag shadow builder
                    null,
                    0          // flags (not currently used, set to 0)
            );
            return true;
        }
    });
    

    还有班级:

    private static class MyDragShadowBuilder extends View.DragShadowBuilder {
    
        int width, height, relativeX, relativeY;
    
        public MyDragShadowBuilder(View v, float relativeX,float relativeY) {
            super(v);
            this.relativeX = (int) relativeX;
            this.relativeY = (int) relativeY;
            width = (v.getWidth());
            height = (v.getHeight());
        }
    
        @Override
        public void onProvideShadowMetrics (@NonNull Point size, @NonNull Point touch){
            size.set(width, height);
            touch.set(relativeX, relativeY);
        }
    
    }
    

    【讨论】:

    • 这几乎解决了问题。唯一的问题是,在我停止拖动它之后,它会笨拙地定位图像。我应该如何进行定位?如果我这样做: view.setX(event.getX()); view.setY(event.getY());它将图像的左上角设置为我停止拖动的位置。如果我这样做: view.setX(event.getX() - (view.getWidth() / 2)); view.setY(event.getY() - (view.getHeight() / 2));然后它将图像居中,但仍会导致尴尬的情况。
    • 我现在明白了。我会添加评论。谢谢!
    • 谢谢。这解决了问题。我唯一添加的是:firstX = e.getX(); firstY = e.getY(); view.setTag(R.id.firstX, firstX); view.setTag(R.id.firstY, firstY);我为ACTION_DOWN的第一个位置放置了标签,拖拽结束后,我将位置设置为:float firstX = (float) view.getTag(R.id.firstX);浮动 firstY = (float) view.getTag(R.id.firstY); view.setX(event.getX() - firstX); view.setY(event.getY() - firstY);
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-13
    • 1970-01-01
    • 1970-01-01
    • 2017-12-17
    • 2014-03-01
    相关资源
    最近更新 更多