可拖拽ListView

前期内容可参考

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










你可能感兴趣的:(android)