Android4.0 Launcher拖拽原理分析1

來源:互聯網
上載者:User

標籤:

在Android4.0源碼內建的Launcher中,拖拽是由DragController進行控制的。

1、基本流程:
  1. 相應的View在檢測到使用者操作後進行判斷,若可以觸發拖拽,則設定自身的相應狀態,然後將待拖拽對象的Bitmap對象、當前位置、拖拽源、待拖拽對象等資訊傳給DragController的startDrag方法啟動拖拽。
  2. 接下來,DragLayer的onInterceptTouchEvent攔截觸屏事件,將其轉到DragController的onTouchEvent方法。
  3. 在DragController的onTouchEvent中調用DragController的handleMoveEvent進行對象的移動,並通知相應拖拽目的對象狀態的改變。
  4. 最後在DragController的onTouchEvent中檢測到抬起事件時調用drop方法釋放待拖拽對象,調用endDrag方法結束拖拽。
2、拖拽開始

  在Launcher中,拖拽有兩種方式觸發:

  1. 在Workspace上進行拖拽;
  2. 從AppsCustomizePagedView中選擇一個應用或Widget放置到Workspace上。
2.1 在Workspace上進行拖拽1) 長按某個表徵圖或Widget

  在這種情況下,會調用Launcher的onLongClick方法,進而對於非檔案夾調用Workspace的startDrag方法來隱藏相應視圖並繪製表徵圖邊界(在Workspace上顯示的用於標識當前拖拽表徵圖所處位置的藍色邊界圖形),最終轉到Workspace.beginDragShared方法。

2) 在開啟的檔案夾中長按某個表徵圖

  在Launcher中,對於檔案夾中元素的長按,是在Folder的onLongClick裡處理的,故長按某個表徵圖或Widget中,對於檔案夾,則直接返回。

  若允許拖拽,則調用Workspace的beginDragShared進行處理。


 

3) Workspace的beginDragShared方法

  從上文中可以發現,只要是在Workspace上啟動物體的拖拽,最終都會走到Workspace.beginDragShared方法裡。在這個方法中,首先會通過createDragBitmap繪製用於拖拽的圖形(包括在原圖外層繪製一圈紅色邊界),然後計算位置與邊界,並將其傳給DragController管理。

 

2.2 從AppsCustomizePagedView中選擇一個應用或Widget放置到Workspace上

  AppsCustomizePagedView繼承自PagedViewWithDraggableItems,即我們平時所說的應用程式抽屜。當長按應用表徵圖或widget時,AppsCustomizePagedView會隱藏,顯示Workspace的縮小狀態,即SPRING_LOADED。

  在源碼中,該狀態轉換有三個入口,均在PagedViewWithDraggableItems中給出,即onInterceptTouchEvent、onTouchEvent與onLongClick。最終都轉到AppsCustomizePagedView的beginDragging方法。但筆者試了多次,發現只有onLongClick被調用。


 

1) AppsCustomizePagedView的beginDragging

beginDragging類似一個代理方法,首先進行Launcher狀態的轉換,然後會根據被拖拽物的不同,調用不同的拖拽方法。


  

2) 應用程式的拖拽beginDraggingApplication

對於應用程式來說,從抽屜拖拽到案頭,介面的隱藏在beginDragging中都已經處理好了,AppsCustomizePagedView不需要儲存任何有關被拖拽應用的資訊(就算取消拖拽,也只需要重新顯示AppsCustomizePagedView就行了,不像Folder那樣還需要恢複捷徑)。因此,只需要通知Workspace繪製表徵圖邊界,然後啟動拖拽即可。

  

3) Widget/捷徑的拖拽beginDraggingWidget

對於Widget列表中的元素,由於有可能為捷徑,因此還需要進行判斷。對不同類型的拖拽物,用不同的方式繪製圖形及表徵圖邊界。

 

3、DragController拖拽控制流程程3.1 startDrag()開始拖拽

  從上文可以發現,無論是以何種方式進入拖拽,最終都是調用DragController的startDrag方法進行處理。

  在DragController中,startDrag是個多態方法,但最終,都走到了以下這個實現中。

 1 public void startDrag(Bitmap b, int dragLayerX, int dragLayerY, DragSource source, Object dragInfo, int dragAction, Point dragOffset, Rect dragRegion) 

  startDrag的邏輯比較清晰,主要是通知相應的監聽器拖拽開始,然後建立拖拽對象及其視圖,將其移動到當前觸摸到位置。

 

3.2 onInterceptTouchEvent()

  DragLayer繼承自ViewGroup,其onInterceptTouchEvent方法若返回true,說明需要攔截觸屏事件,則後續的一系列事件將傳遞給自身的onTouchEvent方法,而不再向其子控制項傳遞。

  DragController的onInterceptTouchEvent由DragLayer的onInterceptTouchEvent調用,用於攔截觸屏事件的處理。當使用者點擊螢幕時,觸發ACTION_DOWN事件,記錄當前觸摸位置。當抬起時,觸發ACTION_UP事件,結束拖拽。若抬起時處於拖拽中,在當前位置釋放被拖拽物(在筆者測試過程中未檢測到其調用)。最後,返回是否處於拖拽狀態。

  因此,若此時處於拖拽中,後續的觸屏事件將只傳遞到DragLayer的onTouchEvent。

  onTouchEvent()

  onTouchEvent由於處理觸屏事件,若返回true,則表示消費掉該事件,事件不再向父控制項的onTouchEvent傳遞。

  DragController的onTouchEvent由DragLayer的onTouchEvent調用,用於處理被拖拽物的移動。

  當startDrag執行完畢,DragController設定拖拽狀態為true,這樣,觸屏事件將最終轉到onTouchEvent中,在此處調用handleMoveEvent進行物體的移動。其基本流程如下。

  

3.3 handleMoveEvent()進行移動

  handleMoveEvent是拖拽的主要方法,當使用者觸發拖拽後,DragController將通過該方法移動被拖拽物視圖,並通知各個釋放目的對象相應狀態的改變。若進入滑屏地區且允許滑屏,執行相應的滑屏操作。如所示。

  

3.4 drop()釋放被拖拽物到當前位置

當使用者將被拖拽物移動到相應位置後,可以將手指從螢幕上移開。此時,將在onInterceptTouchEvent(未試出)與onTouchEvent中調用drop方法釋放被拖拽物。

其主要功能,就是尋找拖拽目的對象(DropTarget),若找到且接受釋放,通知該對象被拖拽物的放入。最後,通知拖拽源(被拖拽物最初所在的容器)拖拽結果。

 

  findDropTarget()尋找當前位置對應的拖拽目標對象

  在handleMoveEvent與drop中,均使用了findDropTarget來尋找當前位置對應的拖拽目的對象,其基本原理就是遍曆所有登入的拖拽目的對象,若其支援放入且當前位置位於該對象的觸發地區內,則匹配成功返回該對象。

 

3.5 DragController拖拽控制流程程總結

Workspace.beginDragShared()/AppsCustomizePagedView.beginDragging() -> startDrag() -> onInterceptTouchEvent() -> onTouchEvent() -> handleMoveEvent() -> drop() -> findDropTarget()

總的來說,DragController拖拽控制就是:

  1. 進入狀態:使用startDrag進入拖拽狀態;
  2. 響應動作:使用onInterceptTouchEvent與onTouchEvent響應使用者的觸屏動作;
  3. 處理移動:使用handleMoveEvent處理被拖拽物的移動;
  4. 釋放移動:使用drop將被拖拽物釋放到相應位置。

http://johnsonxu.iteye.com/blog/1933655

Android4.0 Launcher拖拽原理分析1

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.