接著上篇Android學習系列(10)–App列表之拖拽ListView(上)我們繼續實現ListView的拖拽效果。
7.重寫onTouchEvent()方法。
在這個方法中我們主要是處理拖動和放下。
拖動是選中項的影像隨著手指滑動;放下是在拖動結束的時候交換數據。
方法的整體結構如下:
view sourceprint?01 /**
02 * 觸摸事件
03 */
04 @Override
05 public boolean onTouchEvent(MotionEvent ev) {
06 //如果dragmageView為空,說明攔截事件中已經判定僅僅是點擊,不是拖動,返回
07 //如果點擊的是無效位置,返回,需要重新判斷
08 if(dragImageView!=null&&dragPosition!=INVALID_POSITION){
09 int action = ev.getAction();
10 switch(action){
11 case MotionEvent.ACTION_UP:
12 int upY = (int)ev.getY();
13 //釋放拖動影像
14 stopDrag();
15 //放下後,判斷位置,實現相應的位置刪除和插入
16 onDrop(upY);
17 break;
18 case MotionEvent.ACTION_MOVE:
19 int moveY = (int)ev.getY();
20 //拖動影像
21 onDrag(moveY);
22 break;
23 default:break;
24 }
25 return true;
26 }
27 //這個返回值能夠實現selected的選中效果,如果返回true則無選中效果
28 return super.onTouchEvent(ev);
29 }
8.拖動影像。
拖動的時候,我們調用瞭onDrag(int y)方法,主要做的事情是,讓選中項的影像隨這手指滑動起來。如下:
view sourceprint?1 if(dragImageView!=null){
2 //設置一點點的透明度
3 windowParams.alpha = 0.8f;
4 //更新y坐標位置
5 windowParams.y = y – dragPoint + dragOffset;
6 //更新界面
7 windowManager.updateViewLayout(dragImageView, windowParams);
8 }
當數據集合很大的時候,還需要在拖動到上部區域或者下部區域的時候滾動列表,使用ListView自帶的方法setSelectionFromTop()。
一個可以滾動的拖拽列表雛形就出來瞭,最終onDrag()方法代碼如下:
view sourceprint?01 /**
02 * 拖動執行,在Move方法中執行
03 * @param y
04 */
05 public void onDrag(int y){
06 if(dragImageView!=null){
07 windowParams.alpha = 0.8f;
08 windowParams.y = y – dragPoint + dragOffset;
09 windowManager.updateViewLayout(dragImageView, windowParams);
10 }
11 //為瞭避免滑動到分割線的時候,返回-1的問題
12 int tempPosition = pointToPosition(0, y);
13 if(tempPosition!=INVALID_POSITION){
14 dragPosition = tempPosition;
15 }
16
17 //滾動
18 int scrollHeight = 0;
19 if(y<upScrollBounce){
20 scrollHeight = 8;//定義向上滾動8個像素,如果可以向上滾動的話
21 }else if(y>downScrollBounce){
22 scrollHeight = -8;//定義向下滾動8個像素,,如果可以向上滾動的話
23 }
24
25 if(scrollHeight!=0){
26 //真正滾動的方法setSelectionFromTop()
27 setSelectionFromTop(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的值,急需執行,達到跳過無效位置的效果
09 int tempPosition = pointToPosition(0, y);
10 if(tempPosition!=INVALID_POSITION){
11 dragPosition = tempPosition;
12 }
13
14 //超出邊界處理
15 if(y<getChildAt(0).getTop()){
16 //超出上邊界,設為最小值位置0
17 dragPosition = 0;
18 }else if(y>getChildAt(getChildCount()-1).getBottom()){
19 //超出下邊界,設為最大值位置,註意哦,如果大於可視界面中最大的View的底部則是越下界,所