接着上篇Android学习系列(10)--App列表之拖拽ListView(上)我们继续实现ListView的拖拽效果。
7.重写onTouchEvent()方法。在这个方法中我们主要是处理拖动和放下。拖动是选中项的影像随着手指滑动;放下是在拖动结束的时候交换数据。方法的整体结构如下:
view sourceprint?01 /**
02* 触摸事件
03*/
04 @Override
05 public boolean onTouchEvent(MotionEvent ev) {
06//如果dragmageView为空,说明拦截事件中已经判定仅仅是点击,不是拖动,返回
07//如果点击的是无效位置,返回,需要重新判断
08if(dragImageView!=null&&dragPosition!=INVALID_POSITION){
09int action = ev.getAction();
10switch(action){
11case MotionEvent.ACTION_UP:
12int upY = (int)ev.getY();
13//释放拖动影像
14stopDrag();
15//放下后,判断位置,实现相应的位置删除和插入
16onDrop(upY);
17break;
18case MotionEvent.ACTION_MOVE:
19int moveY = (int)ev.getY();
20//拖动影像
21onDrag(moveY);
22break;
23default:break;
24}
25return true;
26}
27//这个返回值能够实现selected的选中效果,如果返回true则无选中效果
28return super.onTouchEvent(ev);
29 }
8.拖动影像。拖动的时候,我们调用了onDrag(int y)方法,主要做的事情是,让选中项的影像随这手指滑动起来。如下:
view sourceprint?1 if(dragImageView!=null){
2//设置一点点的透明度
3windowParams.alpha = 0.8f;
4//更新y坐标位置
5windowParams.y = y - dragPoint + dragOffset;
6//更新界面
7windowManager.updateViewLayout(dragImageView, windowParams);
8 }
当数据集合很大的时候,还需要在拖动到上部区域或者下部区域的时候滚动列表,使用ListView自带的方法setSelectionFromTop()。一个可以滚动的拖拽列表雏形就出来了,最终onDrag()方法代码如下:
view sourceprint?01 /**
02* 拖动执行,在Move方法中执行
03* @param y
04*/
05 public void onDrag(int y){
06if(dragImageView!=null){
07windowParams.alpha = 0.8f;
08windowParams.y = y - dragPoint + dragOffset;
09windowManager.updateViewLayout(dragImageView, windowParams);
10}
11//为了避免滑动到分割线的时候,返回-1的问题
12int tempPosition = pointToPosition(0, y);
13if(tempPosition!=INVALID_POSITION){
14dragPosition = tempPosition;
15}
16
17//滚动
18int scrollHeight = 0;
19if(y<upScrollBounce){
20scrollHeight = 8;//定义向上滚动8个像素,如果可以向上滚动的话
21}else if(y>downScrollBounce){
22scrollHeight = -8;//定义向下滚动8个像素,,如果可以向上滚动的话
23}
24
25if(scrollHeight!=0){
26//真正滚动的方法setSelectionFromTop()
27setSelectionFromTop(dragPosition, getChildAt(dragPosition-getFirstVisiblePosition()).getTop()+scrollHeight);
28}
29 }
拖动的效果如下:
9.放下影像,数据更新。上面实现了拖动的效果,放下影像后:1)我们要获取放下的位置是数据集合的哪一项;2)在放下位置项插入拖动数据,并删除拖动数据原位置项这些处理写在了onDrop()方法中,在ACTION_UP动作中执行,代码如下:
view sourceprint?01 /**
02* 拖动放下的时候
03* @param y
04*/
05 public void onDrop(int y){
06
07//获取放下位置在数据集合中position
08//定义临时位置变量为了避免滑动到分割线的时候,返回-1的问题,如果为-1,则不修改dragPosition的值,急需执行,达到跳过无效位置的效果
09int tempPosition = pointToPosition(0, y);
10if(tempPosition!=INVALID_POSITION){
11dragPosition = tempPosition;
12}
13
14//超出边界处理
15if(y<getChildAt(0).getTop()){
16//超出上边界,设为最小值位置0
17dragPosition = 0;
18}else if(y>getChildAt(getChildCount()-1).getBottom()){
19//超出下边界,设为最大值位置,注意哦,如果大于可视界面中最大的View的底部则是越下界,所