public class DragGridView extends GridView
{
private String TAG = "DragGridView";
private int dragPosition; //開始拖拽的位置
private int dropPosition; //結束拖拽的位置
private int dragPointX; //相對於item的X座標
private int dragPointY; //相對於item的y座標
private int dragOffsetX;
private int dragOffsetY;
private ImageView dragImageView; //拖動item的preview
private WindowManager windowManager;
private WindowManager.LayoutParams windowParams;
public DragGridView(Context context)
{
super(context);
}
public DragGridView(Context context, AttributeSet attrs)
{
super(context, attrs);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev)
{
Log.d(TAG, "onInterceptTouchEvent" + super.onInterceptTouchEvent(ev));
if (ev.getAction() == MotionEvent.ACTION_DOWN)
{
int x = (int)ev.getX();
int y = (int)ev.getY();
Log.d(TAG, "x=" + x + "getRawx=" + ev.getRawX());
Log.d(TAG, "y=" + y + "getRawY=" + ev.getRawY());
dragPosition = dropPosition = pointToPosition(x, y);
Log.i("TAG", "dragPosition=" + dragPosition);
if (dragPosition == AdapterView.INVALID_POSITION)
{
return super.onInterceptTouchEvent(ev);
}
Log.d(TAG, "getFirstPosition" + getFirstVisiblePosition());
View itemView = (View)getChildAt(dragPosition - getFirstVisiblePosition());
//得到當前點在item內部的位移量即相對於item左上方的座標
Log.d(TAG, "itemview.getLeft=" + itemView.getLeft() + ",itemview.getTop=" + itemView.getTop());
dragPointX = x - itemView.getLeft();//得到觸摸的點,在item 內部相對於它的左邊的點的座標
dragPointY = y - itemView.getTop();
//item 左上方的座標.(x,y)
dragOffsetX = (int)(ev.getRawX() - x);
dragOffsetY = (int)(ev.getRawY() - y);
Log.d(TAG, "dragPointX=" + dragPointX + ",dragPointY=" + dragPointY + ",dragOffsetX=" + dragOffsetX
+ ",dragOffsetY=" + dragOffsetY);
//解決問題3
//每次都銷毀一次cache,重建一個bitmap
itemView.destroyDrawingCache();
itemView.setDrawingCacheEnabled(true);
Bitmap bm = Bitmap.createBitmap(itemView.getDrawingCache());
//建立item的縮圖
startDrag(bm, x, y);
return false;
}
return super.onInterceptTouchEvent(ev);
}
private void startDrag(Bitmap bm, int x, int y)
{
stopDrag();
windowParams = new WindowManager.LayoutParams();
Log.i("xqqLog", "X:" + x + " dragPointX:" + dragPointX + " dragOffsetX:" + dragOffsetX);
windowParams.gravity = Gravity.TOP | Gravity.LEFT; //這個必須加
//得到preview左上方相對於螢幕的座標
windowParams.x = x - dragPointX + dragOffsetX;
windowParams.y = y - dragPointY + dragOffsetY;
//設定寬和高
windowParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
windowParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
windowParams.flags =
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
windowParams.format = PixelFormat.TRANSLUCENT;
windowParams.windowAnimations = 0;
ImageView iv = new ImageView(getContext());
iv.setImageBitmap(bm);
windowManager = (WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE);//"window"
windowManager.addView(iv, windowParams);
dragImageView = iv;
}
@Override
public boolean onTouchEvent(MotionEvent ev)
{
if (dragImageView != null && dragPosition != AdapterView.INVALID_POSITION)
{
switch (ev.getAction())
{
case MotionEvent.ACTION_UP:
int upX = (int)ev.getX();
int upY = (int)ev.getY();
stopDrag();
onDrop(upX,upY);
break;
case MotionEvent.ACTION_MOVE:
int moveX = (int)ev.getX();
int moveY = (int)ev.getY();
Log.d("ACTION_MOVE", "ACTION_MOVE x" + moveX + "ev.getRawx=" + ev.getRawX());
onDrag(moveX,moveY);
break;
}
}
return super.onTouchEvent(ev);
}
private void onDrag(int x, int y)
{
if (dragImageView != null)
{
windowParams.alpha = 0.6f;
// x 表示 相對於這個最邊緣 本身view的布局座標.
// dragPointx 表示相對於item左邊的位置
// dragoffsetX 表示布局相對於 螢幕(0,0)的位置
// x-dragPointx = getLeft();
// y-dragPonitY =getTop();
windowParams.x = x - dragPointX + dragOffsetX;
windowParams.y = y - dragPointY + dragOffsetY;
windowManager.updateViewLayout(dragImageView, windowParams);
}
}
private void onDrop(int x, int y)
{
int tempPosition = pointToPosition(x, y);
if (tempPosition != AdapterView.INVALID_POSITION)
{
dropPosition = tempPosition;
}
if (dropPosition != dragPosition)
{
System.out.println("dragPosition: " + dragPosition + " dropPosition: " + dropPosition);
ImageAdapter adapter = (ImageAdapter)this.getAdapter();
adapter.exchange(dragPosition, dropPosition);
// 解決問題3
/*
* ViewGroup itemView1 = (ViewGroup)getChildAt(dragPosition -
* getFirstVisiblePosition()); ViewGroup itemView2 =
* (ViewGroup)getChildAt(dropPosition - getFirstVisiblePosition());
* itemView1.destroyDrawingCache(); itemView2.destroyDrawingCache();
*/
}
}
private void stopDrag()
{
if (dragImageView != null)
{
windowManager.removeView(dragImageView);
dragImageView = null;
}
}
}