ImageViewをDragShadowBuilderでドラッグする! (Android)

ドラッグとは

ドラッグとはタッチされたものを画面上でタッチに追従移動させることを言います。
つまりタッチされたものとは別に、もう一つ複製を作る必要があります。

ではどうするか

Androidでドラッグアンドドロップするには2つの方法があります。
ひとつはDragShadowBuilder、もうひとつは自力で描画する方法です。
※API Level11以上でDragShadowBuilderを利用することが出来ます。

View.DragShadowBuilder を利用

ここではまずその内の1つ、DragShadowBuilderを利用してImageViewをドラッグさせます。

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    final ImageView imageView = (ImageView)findViewById(R.id.imageView);
    imageView.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            switch (event.getAction() & MotionEvent.ACTION_MASK) {
              case MotionEvent.ACTION_DOWN:
                imageView.setVisibility(View.INVISIBLE);
                ClipData.Item item = new ClipData.Item((CharSequence) v.getTag());
                ClipData dragData = new ClipData(null,new String[]{ClipDescription.MIMETYPE_TEXT_PLAIN}, item);
                View.DragShadowBuilder shadow = new View.DragShadowBuilder(imageView);
                v.startDrag(dragData, shadow, null, 0);
            }
            return true;
        }
    });
}

基本的には公式ページと変わりません。

ただこれだとドラッグ後のイベントが取れません。
このままでは使い道がないので、イベントを取れるようにDragListenerを利用します。

OnDragListener を利用

親のビューにドラッグイベントリスナーをセットします。
ここでは親エレメントがRelativeLayoutなので、それにセットします。
ついでにドラッグ時にImageViewを隠しておきます。

RelativeLayout root = (RelativeLayout)findViewById(R.id.container);
root.setOnDragListener(new View.OnDragListener() {
    @Override
    public boolean onDrag(View v, DragEvent event) {
        switch (event.getAction()) {
            case DragEvent.ACTION_DRAG_STARTED:
                imageView.setVisibility(View.INVISIBLE);
                break;
            case DragEvent.ACTION_DROP:
                // do something 
                break;
            case DragEvent.ACTION_DRAG_ENDED:
                imageView.setVisibility(View.VISIBLE);
                break;
        }
        return true;
    }
});

これでドラッグアンドドロップが出来ました。