可拖拽ListView

xiaoxiao2021-02-28  95

前期内容可参考

 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; } } }

转载请注明原文地址: https://www.6miu.com/read-34935.html

最新回复(0)