2025-04-22

接著上篇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的底部則是越下界,所

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *