android 拖放模型

來源:互聯網
上載者:User

標籤:android   launcher   技術   架構   介面   

英文原文:http://developer.android.com/guide/topics/ui/drag-drop.html

ps:時間過去好久了,這篇文章一直在我的網易雲筆記裡面丟著。我自己都忘了這是我摘抄的網上的童鞋的,還是自己翻譯的。

應該是產生於2013年10月17日,大概在我當時在寫android Launcher的項目時記錄的。

為了不侵犯別個的權益,聰明的我在文章裡撿了幾句話百度了一下,發現有類似的翻譯但是措辭像我這麼犀利的好像沒有。於是權當作自己翻譯的吧。

是的,不要懷疑我,英語四級將將及格也是可以翻譯技術性文章的。


    API Level 11加入 (android 3.0)


    通過安卓的拖放架構,你可以允許使用者使用映像拖放手勢將資料從當前布局的一個view移動到另一個view。這個架構套件括一個拖動事件類別,拖動監聽器,和一些輔助的方法和類。
    雖然這個架構主要是為資料移動設計的,但你也可以為其他的介面動作使用它。比如你可以建立一個應用當使用者把一個顏色表徵圖拖動到另一個表徵圖上時混合兩種顏色。這個主題的剩下部分,描述了資料移動的架構。
概述
    當使用者做了一些你可以識別為開始拖動資料的手勢,一個拖放操作就開始了。作為回應,你的應用程式告訴系統拖動開始了。系統回調你的應用程式來獲得正在被拖動的資料的描述。當使用者的手指在當前布局移動這個描述(一個拖動陰影),系統發送拖動事件給拖動事件監聽器對象和與布局中與view對象聯絡在一起的拖動事件回調方法。一旦使用者釋放這個拖動陰影,系統就結束拖動操作。
    你可以建立一個拖動事件監聽器,通過一個實現View.OnDragListener()的類。通過setOnDragListener()綁定到view。每個view都有一個onDragEvent()的回呼函數。它們的更多細節在拖動事件監聽器和回調方法一節。
    注意:簡單起見,接下來的章節我們稱呼接收拖動事件的常式為拖動事件監聽器,哪怕它其實實際上是一個回調方法。
    當你開始一個拖動,你包括正在移動的資料和描述該資料的中繼資料作為調用系統的一部分。在拖動期間,系統發送拖放事件到監聽器或者布局中每個view的回呼函數。
當拖動停止的時候,監聽器或者回呼函數通過metadata來決定他們是否接受這個拖動。如果接受,系統則把拖動事件的資料發送到監聽器和回呼函數。
    你的應用程式通過調用startDrag()來告訴系統開始一個拖動。這告訴系統開始發送拖動事件,同事也發送你拖動的資料。
    你可以為當前布局中的其他附加view調用startDrag(),系統知識通過這個view對象來擷取你布局中的全域配置的屬性。
    一旦你的應用程式調用了startDrag(),剩下的流程使用系統發送給view對象的event。
拖放流程
    拖放過程主要有四個步驟或者狀態:
Started
    響應使用者的手勢開始一個拖動,應用程式調用startDrag()來告訴系統啟動一個拖動。startDrag()的參數提供了被拖動的資料,它的metadata,還有繪製拖動陰影的回調。
    系統首先通過回調到應用程式來擷取拖動陰影,然後再裝置上顯示拖動陰影。
    接下來,系統發送action type為ACTION_DRAG_STARTED的拖動事件給當前布局上所有view對象的拖動事件監聽器。為了繼續接受拖動事件,包括可能的drop事件,監聽器必須返回true.這是向系統註冊監聽器。只有註冊過的監聽器才能繼續接收拖動事件。在這一點上,監聽器也可以改變他們view對象的外觀來表示監聽器能接收拖動事件。
    如果監聽器返回false,那麼它將不能接收當前操作的拖動事件直到系統發送了一個action type為ACTION_DRAG_ENDED的拖動事件。通過發送false,監聽器告訴系統,它對這個拖動操作不感興趣,不想繼續接收拖動資料。
Continuing
    使用者繼續拖動。當拖動陰影貫穿view對象的邊框,系統會發送一個或多個拖動事件給view對象的拖動監聽器(如果已經註冊接收事件)。監聽器可能選擇改變view對象的外觀來響應事件。比如,如果事件表示拖動陰影進入view(action typeACTION_DRAG_ENTERED)的邊框地區,監聽器可以高亮view來響應。
Dropped
    使用者在一個能接收它的view的邊框區釋放拖動陰影。系統發送給view對象一個action type為ACTION_DROP的拖動事件。該拖動事件包含了在啟動這個操作時候通過startDrag()操作傳給系統的資料。如果代碼接收成功,監聽器被期望返回true給系統。
    注意,這一步只發生在當使用者在其監聽器被註冊接收拖動事件的view的邊框區放下拖動陰影時。如果使用者在其他任何情況下釋放拖動陰影,則沒有ACTION_DROP拖動事件被發送。
Ended
    在使用者釋放拖動陰影后,在系統發送ACTION類型為ACTION_DROP的拖動事件後,系統發送一個ACTION類型為ACTION_DRAG_ENDED的拖動事件來表示拖動操作結束。這樣做是不管使用者在哪釋放了拖動陰影。這個事件被發送給每一個註冊接收拖動事件的監聽器,即使監聽器接收到了ACTION_DROP事件。
拖動事件監聽器和回調方法
    一個view可以通過實現View.OnDragListener的拖動事件監聽器或者view的onDragEvent方法來接收拖動事件。當系統調用回調方法或者監聽器時,傳遞給他們一個DragEvent對象。
    大多數情況下你可能會更想用監聽器。當設計介面時,通常不用子類化view類,但是使用回呼函數強迫你必須這麼做,為了重寫方法。比較而言,你可以實現一個監聽器類,然後在幾個不同的view對象使用它。你還可以以匿名內部類的方式實現監聽器。把監聽器綁定給view對象,需要調用setOnDragListener()。
    你可以再一個view對象中同時有監聽器和回調方法。這種情況下,系統首先調用監聽器。除非監聽器返回false,否則系統不會繼續調用回調方法。
    onDragEvent(DragEvent) 和View.OnDragListener的聯絡就好像在觸摸事件中onTouchEvent() 和View.OnTouchListener的關係。
拖動事件
    系統以DragEvent對象的形式發出一個拖動事件。這個對象包含了一個action類型,用來告訴監聽器在拖放過程中發生了什麼。這個對象還包含了其他資料,依據action類型。
    為了擷取action類型,監聽器調用getAction()。有六種可能的值,在DragEvent類中以常量的形式定義。
    拖動事件對象還包含了應用程式在startDrag()中提供給系統的資料。有些資料只有在特定的action類型時才有效。

    getAction(), describeContents(), writeToParcel(), 和toString()總是返回有效資料。
    如果方法不包含有效資料,則依據其返回值類型,返回null或者0.
拖動陰影
    在一個拖放操作中,系統顯示一個使用者拖動的映像。對於資料移動,這張照片代表了被拖動的資料。對其他動作,映像代表了一些方面的拖動操作。
    這個映像被稱作拖動陰影。你可以使用你View.DragShadowBuilder對象聲明的方法建立它,然後當你開始一個拖動的時候使用startDrag()傳遞給系統。作為startDrag()的響應,系統調用你在View.DragShadowBuilder中定義的回調方法來獲得一個拖動陰影。
    View.DragShadowBuilder有兩個構造器:
        View.DragShadowBuilder(View)
        View.DragShadowBuilder()
    View.DragShadowBuilder有兩個方法:
        onProvideShadowMetrics()
        onDrawShadow()
    為了提高效能,你應當保持這個拖動陰影的尺寸足夠小。單個項目中,你可能使用一個表徵圖。多重專案中,你可能想要使用棧中的表徵圖,而不是展開在螢幕的完整映像。
設計一個拖放操作
    這一節一步步展示了如何開始一個拖動,如何想要拖動過程中的事件,如何響應放開事件,如何結束拖放操作。
開始一個拖放

    使用者通過一個拖動手勢來開始一個拖動,通常是在一個view對象的長按。作為響應,你應當;
    1、必要時為正要被移動的資料建立ClipData和ClipData.Item。ClipData提供儲存在其內部ClipDescription對象的中繼資料。對於不代表資料移動的拖放操作,你可能希望通過null來代替實際的對象。
    比如,
    2、以下程式碼片段定義了myDragShadowBuilder.它為拖動一個文本視圖建立了一個小的灰色舉行作為拖動陰影。
    注意:你並不是必須要繼承View.DragShadowBuilder.構造器View.DragShadowBuilder(View)以觸碰點為中心建立一個預設的跟傳入的view一樣大小的拖動陰影。
響應一個拖動開始
    在拖動操作過程中,系統分發拖動事件給當前布局中view對象的拖動事件監聽器。監聽器應當通過調用getAction()來擷取action類型。在拖動的開始,這個方法返回ACTION_DRAG_STARTED.
    響應一個ACTION_DRAG_STARTED的事件,監聽器需要如下做:
    1、調用getClipDescription()來擷取ClipDescription。使用ClipDescription中的MIME類型方法來看是否監聽器能接收正在被拖動的資料。
    如果拖放操作不代表資料移動,這可能不是必須的。
    2、如果監聽器能接收放開,它應當返回true。這告訴系統繼續發送拖動事件給該監聽器。如果不能接收放開事件,應當返回false,系統就會停止發送拖動事件直到發出ACTION_DRAG_ENDED。
    注意:對於一個ACTION_DRAG_STARTED事件,DragEvent中的getClipData() \ getX() \ getY() \ getResult()是無效的。
處理拖動過程中的事件
    在拖動過程中,對ACTION_DRAG_STARTED拖動事件返回true作為響應的監聽器會繼續接收拖動事件。監聽器在拖動過程中接收到的拖動事件的類型,取決於拖動陰影的位置和監聽器view的可見度。
    在拖動過程中,監聽器主要使用拖動事件來決定是否應當改變view的外形。
    在拖動過程中,getAction()返回下面3個值中的一個:
ACTION_DRAG_ENTERED:當觸碰點進入監聽器的view的邊框區時,監聽器接收到這個事件。
ACTION_DRAG_LOCATION:一旦監聽器接收到ACTION_DRAG_ENTERED事件,在它接收到ACTION)DRAG_EXITED之前,觸碰點每次移動都會接收到一個新的ACTION_DRAG_LOCATION事件。getX和getY方法返回觸碰點的座標。
ACTION_DRAG_EXITED:在拖動陰影不再在該監聽器的view的邊框區之內,這個事件發送給一個以前接收到ACTION_DRAG_ENTERED的監聽器。
    監聽器不需要響應其他action類型。如果監聽器返回一個值給系統,將被忽略。下面是一些響應這些action類型的指導:
    響應ACTION_DRAG_ENTERED和ACTION_DRAG_LOCATION,監聽器可以改變view的外形來表示它可以接收放開。
    action類型為ACTION_DRAG_LOCATION的事件包含getX和getY的有效資料,對應觸碰點的位置。監聽器可能需要這些資訊來改變在觸碰點上的view的外形。監聽器也可以使用這些資訊來決定使用者將要放開拖動陰影的準確位置。
    響應ACTION_DRAG_EXITED,監聽器需要重設為響應ACTION_DRAG_ENTERED或ACTION_DRAG_LOCATION而改變的外形。這表明這個view不再是放開目標。
響應放開
    當使用者在應用程式的view上釋放拖動陰影,並且這個view之前已經報告它可以接收正在被拖動的內容,系統會分發一個類型為ACTION_DROP的事件給這個view.監聽器需要如下做:
    1.調用getClipData()來擷取最初是由startDrag()提供的ClipData對象,並儲存它。如果拖放操作不是代表資料移動,這不是必須的。
    2.返回true表示放開操作被成功處理,false表示不成功。ACTION_DRAG_ENDED事件的getResult()的值作為返回值。
    注意;如果系統沒有發出ACTION_DROP事件,ACTION_DRAG_ENDED的getResult()返回false。
    對於ACTION_DROP事件,getX和getY返回在放開時拖動點的位置,使用接收這個放開的view的座標系統。
    系統允許使用者在一個不接收拖動事件的view上釋放拖動陰影。也允許使用者在應用程式介面的空地區,或者應用程式之外的地區釋放拖動陰影。在這些情況下,系統不會發出一個ACTION_DROP事件,但它會發送ACTION_DRAG_ENDED事件。

響應拖動結束
    使用者一釋放拖動陰影,系統就發送一個ACTION_DRAG_ENDED的拖動事件給應用程式中的所有拖動事件監聽器。這用來表示拖動操作結束了。
    每個監聽器應當如下做:
    1.如果操作期間監聽器改變了view對象的外觀,應當重設為預設面板。這是給使用者一個可視的表示操作結束了。
    2.監聽器可選擇的調用getResult()來找出操作的更多資訊。如果監聽器返回true來響應ACTION_DROP,getResult()返回true.其他情況下getResult()返回false,包括系統沒有發出ACTION_DROP事件的情況。
    3.監聽器應當返回true給系統。




android 拖放模型

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.