前期内容可参考
1. WindowManager.LayoutParams详解总结和对应实例
2. Android 自定义可拖拽ListView,思想最重要。
备忘代码如下:
public class DragListView extends ListView {
private BaseAdapter mAdapter;
private WindowManager mWindowManager;
private WindowManager.LayoutParams mWindowLayoutParams;
private Vibrator mVibrator;
private int mSelectedPosition;
private Bitmap mDragBmp;
;
private ImageView mDragImg;
private boolean isDrag = false;
private int mDownX;
private int mDownY;
private int mPoint2ItemTop;//按下的点到所在item的上边缘的距离
private int mOffset2Top; //DragListView距离屏幕顶部的偏移量
private int mDownScrollBorder;
private int mUpScrollBorder;
private int speed = 20;
private View mSelectedItemView;
private Handler mHandler = new Handler();
private long mLongClickTime = 1000;
private List<?> mListData;
public DragListView(Context context) {
super(context);
init();
}
public DragListView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public DragListView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
/**
* TODO 需要在调用完setAdapter后,接着调用这个,Adapter必须是BaseAdapter的子类
*
* @param data
*/
public void setListData(List<?> data) {
mListData = data;
mAdapter = (BaseAdapter) getAdapter();
}
private void init() {
mAdapter = (BaseAdapter) getAdapter();
mVibrator = (Vibrator) getContext().getSystemService(Context.VIBRATOR_SERVICE);
mWindowManager = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
//setOnItemLongClickListener();
}
private Runnable mLongClickRunnable = new Runnable() {
@Override
public void run() {
isDrag = true;
mVibrator.vibrate(100);
createDragImage();
if (mSelectedItemView != null) {
mSelectedItemView.setVisibility(View.INVISIBLE);
}
}
};
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mDownX = (int) event.getX();
mDownY = (int) event.getY();
mSelectedPosition = pointToPosition(mDownX, mDownY);
if (mSelectedPosition == AdapterView.INVALID_POSITION) {
return super.onTouchEvent(event);
}
mSelectedItemView = getChildAt(mSelectedPosition - getFirstVisiblePosition());
mHandler.postDelayed(mLongClickRunnable, mLongClickTime);
mPoint2ItemTop = mDownY - mSelectedItemView.getTop();
mOffset2Top = (int) (event.getRawY() - mDownY);
mDownScrollBorder = getHeight() / 4;
mUpScrollBorder = getHeight() * 3 / 4;
break;
case MotionEvent.ACTION_MOVE:
if (isDrag) {
mDownX = (int) event.getX();
mDownY = (int) event.getY();
onDragStart();
}
break;
case MotionEvent.ACTION_UP:
onDragStop();
mHandler.removeCallbacks(mLongClickRunnable);
isDrag = false;
break;
}
return super.onTouchEvent(event);
}
private void createDragImage() {
mSelectedItemView.setDrawingCacheEnabled(true);
mDragBmp = Bitmap.createBitmap(mSelectedItemView.getDrawingCache());
mSelectedItemView.setDrawingCacheEnabled(false);
mSelectedItemView.destroyDrawingCache();
mWindowLayoutParams = new WindowManager.LayoutParams();
mWindowLayoutParams.alpha = 0.5f;
mWindowLayoutParams.format = PixelFormat.RGBA_8888;
mWindowLayoutParams.gravity = Gravity.TOP | Gravity.LEFT;
mWindowLayoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
mWindowLayoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
mWindowLayoutParams.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
| WindowManager.LayoutParams.FLAG_FULLSCREEN;
mWindowLayoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
mWindowLayoutParams.x = 0;
mWindowLayoutParams.y = mDownY - mPoint2ItemTop + mOffset2Top;
mDragImg = new ImageView(getContext());
mDragImg.setImageBitmap(mDragBmp);
mWindowManager.addView(mDragImg, mWindowLayoutParams);
}
private void onDragStart() {
if (mWindowLayoutParams != null && mDragImg != null) {
mWindowLayoutParams.x = 0;
mWindowLayoutParams.y = mDownY - mPoint2ItemTop + mOffset2Top;
mWindowManager.updateViewLayout(mDragImg, mWindowLayoutParams);
}
int scrollY;
if (mDownY > mUpScrollBorder) {
scrollY = speed;
} else if (mDownY < mDownScrollBorder) {
scrollY = -speed;
} else {
scrollY = 0;
}
smoothScrollBy(scrollY, 0);
int position = pointToPosition(mDownX, mDownY);
if (position != mSelectedPosition && position != AdapterView.INVALID_POSITION) {
if (mListData != null) {
if (mSelectedPosition < position) {
for (int i = mSelectedPosition; i < position; i++) {
Collections.swap(mListData, i, i + 1);
}
} else if (mSelectedPosition > position) {
for (int i = mSelectedPosition; i > position; i--) {
Collections.swap(mListData, i, i - 1);
}
}
mAdapter.notifyDataSetChanged();
}
View view1 = getChildAt(mSelectedPosition - getFirstVisiblePosition());
if (view1 != null) {
view1.setVisibility(View.VISIBLE);
}
View view2 = getChildAt(position - getFirstVisiblePosition());
if (view2 != null) {
view2.setVisibility(View.INVISIBLE);
}
mSelectedPosition = position;
}
}
private void onDragStop() {
View view = getChildAt(mSelectedPosition - getFirstVisiblePosition());
if (view != null) {
view.setVisibility(View.VISIBLE);
}
if (mWindowLayoutParams != null && mDragImg != null) {
mWindowManager.removeView(mDragImg);
mDragImg = null;
mDragBmp.recycle();
mDragBmp = null;
}
}
}