Android API之Drag&Drop

官方介绍:https://developer.android.com/guide/topics/ui/drag-drop.html#AboutDragging

public class MainActivity extends AppCompatActivity {
    private ImageView testIv;
    private static final String TAG = "imageView";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        testIv = (ImageView) findViewById(R.id.test_iv);
        testIv.setTag(TAG);
        initEvents();
    }

    private void initEvents() {
        testIv.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                // ClipData.Item对象中包含文字、URI或者Intent数据。一个clip对象中可以包含一个或多个Item对象。
                ClipData.Item item = new ClipData.Item(testIv.getTag().toString());
                //ClipData代表剪贴板中剪切数据
                ClipData dragData = new ClipData(v.getTag().toString(), new String[]{ClipDescription.MIMETYPE_TEXT_PLAIN}, item);
                //拖放阴影构造者对象,用于构造拖放阴影。
                View.DragShadowBuilder myShadow = new MyDragShadowBuilder(testIv);
                // 开始拖动
                testIv.startDrag(dragData, myShadow, null, 0);
                return false;
            }
        });
        testIv.setOnDragListener(new myDragEventListener());
    }

    //定义了一个myDragShadowBuilder类,它创建一个用于拖拽TextView对象的小的灰色的矩形作为DragShadow
    private static class MyDragShadowBuilder extends View.DragShadowBuilder {
        private static Drawable shadow;

        //构造器接收任意的应用程序的View对象
        public MyDragShadowBuilder(View v) {
            super(v);
            shadow = new ColorDrawable(Color.LTGRAY);
        }

        /**
         * 在你调用startDrag()方法后,系统会立即调用这个方法,给系统发送拖拽影子的尺寸和触点。这个方法有两个参数:
         * size:一个Point对象,其中X代表影子的宽度,Y代表影子的高度;
         * touch:一个Point对象,这个触点应该是拖拽期间用户手指下方的拖拽影子的位置,X代表x轴的坐标,Y代表y轴的坐标。
         *
         * @param size
         * @param touch
         */
        @Override
        public void onProvideShadowMetrics(Point size, Point touch) {
            int width, height;
            width = getView().getWidth() / 2;
            height = getView().getHeight() / 2;
            shadow.setBounds(0, 0, width, height);
            size.set(width, height);
            touch.set(width / 2, height / 2);
        }

        /**
         * 调用onProviderShadowMetrics()回调之后,系统会立即调用onDrawShadow()方法来获得拖拽影子。
         * 这个方法有一个画布参数(Canvas对象),系统会使用onProvideShadowMetrics()方法中提供的参数来构造这个Canvas对象,
         * 并在这个对象中描画拖拽影子。
         *
         * @param canvas
         */
        @Override
        public void onDrawShadow(Canvas canvas) {
            shadow.draw(canvas);
        }
    }

    //所有的拖拽事件都会被拖拽事件的回调方法或监听器接收。
    class myDragEventListener implements View.OnDragListener {
        public boolean onDrag(View v, DragEvent event) {
            final int action = event.getAction();
            switch (action) {
                //只在应用程序调用startDrag()方法,并且获得了拖拽影子后,View对象的拖拽事件监听器才接收这种事件操作。
                case DragEvent.ACTION_DRAG_STARTED:
                    if (event.getClipDescription().hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN)) {
                        testIv.setColorFilter(Color.BLUE);
                        testIv.invalidate();
                        return true;

                    }
                    return false;
                //当拖拽影子刚进入View对象的边框时,View对象的拖拽事件监听器会接收这种事件操作类型。
                case DragEvent.ACTION_DRAG_ENTERED:
                    testIv.setColorFilter(Color.GREEN);
                    testIv.invalidate();
                    return true;
                //在View对象收到一个ACTION_DRAG_ENTERED事件之后,并且拖拽影子依然还在这个对象的边框之内时,
                // 这个View对象的拖拽事件监听器会接收这种事件操作类型
                case DragEvent.ACTION_DRAG_LOCATION:
                    return true;
                //View对象收到一个ACTION_DRAG_ENTERED和至少一个ACTION_DRAG_LOCATION事件之后,这个对象的事件监听器会接受这种操作类型。
                case DragEvent.ACTION_DRAG_EXITED:
                    testIv.setColorFilter(Color.BLUE);
                    testIv.invalidate();
                    return true;
                //当用户在一个View对象之上释放了拖拽影子,这个对象的拖拽事件监听器就会收到这种操作类型。
                // 如果这个监听器在响应ACTION_DRAG_STARTED拖拽事件中返回了true,那么这种操作类型只会发送给一个View对象。
                // 如果用户在没有被注册监听器的View对象上释放了拖拽影子,或者用户没有在当前布局的任何部分释放操作影子,
                // 这个操作类型就不会被发送。如果View对象成功的处理放下事件,监听器要返回true,否则应该返回false。
                case DragEvent.ACTION_DROP:
                    // Gets the item containing the dragged data
                    ClipData.Item item = event.getClipData().getItemAt(0);
                    CharSequence dragData = item.getText();
                    Toast.makeText(MainActivity.this, "Dragged data is " + dragData.toString(), Toast.LENGTH_LONG).show();
                    testIv.clearColorFilter();
                    testIv.invalidate();
                    return true;
                //当系统结束拖拽操作时,View对象拖拽监听器会接收这种事件操作类型。
                // 这种操作类型之前不一定是ACTION_DROP事件。如果系统发送了一个ACTION_DROP事件,
                // 那么接收ACTION_DRAG_ENDED操作类型不意味着放下操作成功了。
                // 监听器必须调用getResult()方法来获得响应ACTION_DROP事件中的返回值。
                // 如果ACTION_DROP事件没有被发送,那么getResult()会返回false。
                case DragEvent.ACTION_DRAG_ENDED:
                    testIv.clearColorFilter();
                    testIv.invalidate();
                    if (event.getResult()) {
                        Toast.makeText(MainActivity.this, "The drop was handled.", Toast.LENGTH_LONG).show();
                    } else {
                        Toast.makeText(MainActivity.this, "The drop didn't work.", Toast.LENGTH_LONG).show();
                    }
                    return true;
                default:
                    Log.e("DragDrop Example", "Unknown action type received by OnDragListener.");
                    break;
            }

            return false;
        }
    }

    ;
}
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值