思路:1、长按视为开始拖动,根据poionToPosition()获取当前点击的itemView,并隐藏
2、调用windowManager.addView()添加当前itemView的镜像
3、在onTouchEvent中获取手指移动的moveX,moveY,不断重绘镜像
4、在相应位置更改item数据,直接调用adapter.nodifyDataSetChanged();
5、显示当前位置的item,并释放镜像资源,完成交换
注意:
图中红色框为我们的GridView
1:mPoint2ItemTop点击坐标到该itemView的上边距
event.getX()-itemView.getLeft();
2:mPoint2ItemLeft点击坐标到该itemView的左边距
event.getY()-itemView.getTop();
3:mOffsetTop GridView到屏幕上方的偏移值
event.getRawY()-event.getY();
mDownX - mPoint2ItemLeft + mOffsetLeft
4:mOffsetLeftGridView到屏幕左边的偏移值
event.getRawX()-event.getX();
5:mStartDownScrollHeight 滑动到该位置开始向下滚动
GridView.getHeight() / 4;
6:mStartUpScrollHeight滑动到该位置开始向上滚动
GridView.getHeight() *3 /4;
GetRawX():相对于屏幕原点的X轴坐标
GetX():相对于父空间的X轴坐标
getLeft():相对于父控件坐标
注意:当listView或者GridView滚动之后,getChildAt()获取的子组件可能为空,
此方法为获取当前可视的视图,如果需要正确获取当前屏幕中显示的第几个控件需:
getChildAt(mDragPosition- getFirstVisiblePosition()
代码实现:
package com.example.draggridview;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.os.Handler;
import android.os.Vibrator;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.ImageView;
public class DragGridView extends GridView {
private static final String TAG = "DragGridView";
private static final int scrollSpeed = 20;
/**
* 长按视为拖动图标
*/
private long dragRespondTime = 1000;
/**
* 手指按下的点坐标
*/
private int mDownX, mDownY;
/**
* 手指移动的距离
*/
private int moveX, moveY;
/**
* 手指按下坐标到该item的边缘偏移值
*/
private int mPoint2ItemTop, mPoint2ItemLeft;
/**
* 开始自动滚动的高度
*/
private int mStartUpScrollHeight, mStartDownScrollHeight;
/**
* 状态栏高度
*/
private int mStatusHeight = 0;
/**
* 手指按下坐标到屏幕边框的偏移值
*/
private int mOffsetTop, mOffsetLeft;
/**
* 手指按下的position
*/
private int mDragPosition = 0;
/**
* 手指按下的view
*/
private View mStartDragItemView;
/**
* 镜像view
*/
private Bitmap mDragBitmap;
/**
* 镜像imageview组件
*/
private ImageView mDragImageView;
WindowManager.LayoutParams winLayoutParams;
/**
* 是否支持拖动界面
*/
private boolean isDrag = false;
OnItemChangerListener listener;
/**
* 震动
*/
private Vibrator vibrator;
private WindowManager windowManager;
private Handler handler = new Handler();
private Runnable dragRunnable = new Runnable() {
@Override
public void run() {
isDrag = true;
// 隐藏当前点击的item
mStartDragItemView.setVisibility(View.INVISIBLE);
// 震动
vibrator.vibrate(50);
// 生成镜像
createDr