实现方法:
首先需要定义一个支持拖动的源组件和一个作为Drop区域的目标组件。
在支持拖动的组件中注册OnTouchListener 或LongClickListener监听事件,构建一个ClipData对象,这个对象用来从源组件向Drop区域传递数据
使用DragShadowBuilder指定拖动操作的阴影效果
拖动的组件主要代码部分如下:
// Assign the touch listener to your view which you want to move
findViewById(R.id.myimage1).setOnTouchListener(new MyTouchListener());
// This defines your touch listener
private final class MyTouchListener implements OnTouchListener {
public boolean onTouch(View view, MotionEvent motionEvent) {
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
ClipData data = ClipData.newPlainText("", "");
DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view);
view.startDrag(data, shadowBuilder, view, 0);
view.setVisibility(View.INVISIBLE);
return true;
} else {
return false;
}
}
}
接下来在定义为Drop区域的组件中注册OnDragListener监听事件
主要代码:
findViewById(R.id.bottomright).setOnDragListener(new MyDragListener()); class MyDragListener implements OnDragListener { Drawable enterShape = getResources().getDrawable(R.drawable.shape_droptarget); Drawable normalShape = getResources().getDrawable(R.drawable.shape); @Override public boolean onDrag(View v, DragEvent event) { int action = event.getAction(); switch (event.getAction()) { case DragEvent.ACTION_DRAG_STARTED: // Do nothing break; case DragEvent.ACTION_DRAG_ENTERED: v.setBackgroundDrawable(enterShape); break; case DragEvent.ACTION_DRAG_EXITED: v.setBackgroundDrawable(normalShape); break; case DragEvent.ACTION_DROP: // Dropped, reassign View to ViewGroup View view = (View) event.getLocalState(); ViewGroup owner = (ViewGroup) view.getParent(); owner.removeView(view); LinearLayout container = (LinearLayout) v; container.addView(view); view.setVisibility(View.VISIBLE); break; case DragEvent.ACTION_DRAG_ENDED: v.setBackgroundDrawable(normalShape); default: break; } return true; } }
完整代码如下:
public class DragActivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); findViewById(R.id.myimage1).setOnTouchListener(new MyTouchListener()); findViewById(R.id.myimage2).setOnTouchListener(new MyTouchListener()); findViewById(R.id.myimage3).setOnTouchListener(new MyTouchListener()); findViewById(R.id.myimage4).setOnTouchListener(new MyTouchListener()); findViewById(R.id.topleft).setOnDragListener(new MyDragListener()); findViewById(R.id.topright).setOnDragListener(new MyDragListener()); findViewById(R.id.bottomleft).setOnDragListener(new MyDragListener()); findViewById(R.id.bottomright).setOnDragListener(new MyDragListener()); } private final class MyTouchListener implements OnTouchListener { public boolean onTouch(View view, MotionEvent motionEvent) { if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) { ClipData data = ClipData.newPlainText("", ""); DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view); view.startDrag(data, shadowBuilder, view, 0); view.setVisibility(View.INVISIBLE); return true; } else { return false; } } } class MyDragListener implements OnDragListener { Drawable enterShape = getResources().getDrawable(R.drawable.shape_droptarget); Drawable normalShape = getResources().getDrawable(R.drawable.shape); @Override public boolean onDrag(View v, DragEvent event) { int action = event.getAction(); switch (event.getAction()) { case DragEvent.ACTION_DRAG_STARTED: // Do nothing break; case DragEvent.ACTION_DRAG_ENTERED: v.setBackgroundDrawable(enterShape); break; case DragEvent.ACTION_DRAG_EXITED: v.setBackgroundDrawable(normalShape); break; case DragEvent.ACTION_DROP: // Dropped, reassign View to ViewGroup View view = (View) event.getLocalState(); ViewGroup owner = (ViewGroup) view.getParent(); owner.removeView(view); LinearLayout container = (LinearLayout) v; container.addView(view); view.setVisibility(View.VISIBLE); break; case DragEvent.ACTION_DRAG_ENDED: v.setBackgroundDrawable(normalShape); default: break; } return true; } } }
布局文件:
<?xml version="1.0" encoding="utf-8"?> <GridLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:columnCount="2" android:columnWidth="300dp" android:orientation="vertical" android:rowCount="2" android:stretchMode="columnWidth" > <LinearLayout android:id="@+id/topleft" android:layout_width="160dp" android:layout_height="200dp" android:layout_column="0" android:layout_row="0" android:background="@drawable/shape" > <ImageView android:id="@+id/myimage1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_column="0" android:layout_row="0" android:src="@drawable/ic_launcher" /> </LinearLayout> <LinearLayout android:id="@+id/topright" android:layout_width="160dp" android:layout_height="200dp" android:layout_column="1" android:layout_row="0" android:background="@drawable/shape" > <ImageView android:id="@+id/myimage2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_column="0" android:layout_row="0" android:src="@drawable/ic_launcher" /> </LinearLayout> <LinearLayout android:id="@+id/bottomleft" android:layout_width="160dp" android:layout_height="200dp" android:layout_column="0" android:layout_row="1" android:background="@drawable/shape" > <ImageView android:id="@+id/myimage3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_launcher" /> </LinearLayout> <LinearLayout android:id="@+id/bottomright" android:layout_width="160dp" android:layout_height="200dp" android:layout_column="1" android:layout_row="1" android:background="@drawable/shape" > <ImageView android:id="@+id/myimage4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_column="0" android:layout_row="0" android:src="@drawable/ic_launcher" /> </LinearLayout> </GridLayout>
shape.xml:
<?xml version="1.0" encoding="UTF-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" > <stroke android:width="2dp" android:color="#FFFFFFFF" /> <gradient android:angle="225" android:endColor="#DD2ECCFA" android:startColor="#DD000000" /> <corners android:bottomLeftRadius="7dp" android:bottomRightRadius="7dp" android:topLeftRadius="7dp" android:topRightRadius="7dp" /> </shape>
shape_droptarget.xml:
<?xml version="1.0" encoding="UTF-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" > <stroke android:width="2dp" android:color="#FFFF0000" /> <gradient android:angle="225" android:endColor="#DD2ECCFA" android:startColor="#DD000000" /> <corners android:bottomLeftRadius="7dp" android:bottomRightRadius="7dp" android:topLeftRadius="7dp" android:topRightRadius="7dp" /> </shape>