可拖拽ListView

原创 2017年05月05日 17:15:01

前期内容可参考

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










相关文章推荐

自定义控件——可拖拽排序的ListView

前言最经研究了一下拖拽排序的ListView,跟酷狗里的播放列表排序一样,但因为要添加自己特有的功能,所以研究了好长时间。一开始接触的是GitHub的开源项目——DragSortListView,实现...
  • a10615
  • a10615
  • 2016年05月12日 01:44
  • 11334

实现ListView右侧的快速拖动条

看到很多ListView都有快速拖动条,于是百度查了一下:添加andr

拖动实现listview的item改变顺序(DragSortListView)

用开源库DragSortListView做了一个demo,是用于拖拽改变listview中的item顺序的。
  • hjqjl
  • hjqjl
  • 2015年10月27日 17:17
  • 1353

实现可拖动排序的ListView-DragListView

项目 中要用到拖动排序的效果,于是百度到网上的做法,github上开源框架被我pass, 为了一个小功能导入一库太不划算。然后看到这遍 http://blog.csdn.net/jj120522/ar...

可拖拽的listView

  • 2017年11月01日 15:00
  • 180KB
  • 下载

Android学习系列(11)--App列表之拖拽ListView(下)

接着上篇Android学习系列(10)--App列表之拖拽ListView(上)我们继续实现ListView的拖拽效果。 7.重写onTouchEvent()方法。      在这个方法中我们主要是...
  • gpfwcx
  • gpfwcx
  • 2014年04月03日 00:42
  • 253

WPF中ListView拖拽效果

  • 2016年03月06日 19:39
  • 10KB
  • 下载

可拖拽Item的ListView

  • 2014年02月08日 09:34
  • 411KB
  • 下载

android ListView和GridView拖拽移位实现代码

http://www.jb51.net/article/32434.htm 关于ListView拖拽移动位置,想必大家并不陌生,比较不错的软件都用到如此功能了.如:搜狐,网易,百度等,但是相比来说还...
  • shotaSu
  • shotaSu
  • 2016年02月19日 10:57
  • 489
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:可拖拽ListView
举报原因:
原因补充:

(最多只允许输入30个字)