Android View事件機制 21問21答

發表於2016-04-12

1.View的座標引數 主要有哪些?分別有什麼注意的要點?

答:Left,Right,top,Bottom 注意這4個值其實就是 view 和 他的父控制元件的 相對座標值。 並非是距離螢幕左上角的絕對值,這點要注意。

此外,X和Y 其實也是相對於父控制元件的座標值。 TranslationX,TranslationY 這2個值 預設都為0,是相對於父控制元件的左上角的偏移量。

換算關係:

x=left+tranX,y=top+tranY.

很多人不理解,為什麼事這樣,其實就是View 如果有移動的話,比如平移這種,你們就要注意了,top和left 這種值 是不會變化的。

無論你把view怎麼拖動,但是 x,y,tranX,tranY 的值是隨著拖動平移 而變化的。想明白這點 就行了。

2.onTouchEvent和GestureDetector 在什麼時候用哪個比較好?

答:只有滑動需求的時候 就用前者,如果有雙擊等這種行為的時候 就用後者。

3.Scroller 用來解決什麼問題?

答:view的scrollTo和scrollBy 滑動效果太差了,是瞬間完成。而scroller可以配合view的computeScroll 來完成 漸變的滑動效果。體驗更好。

4.ScrollTo和ScrollBy 有什麼需要注意的?

答:前者是絕對滑動,後者是相對滑動。滑動的是view的內容 而不是view本身。這很重要。比如textview 呼叫這2個方法  滑動的就是顯示出來的字的內容。

一般而言 我們用scrollBy會比較多一些。傳值的話 其實 記住幾個法則就可以了。 右-左 x為正 否則x為負  上-下 y為負,否則y為正。

可以稍微看一下 這2個的原始碼:

看到裡面有2個變數 mScrollX 和mScrollY 這2個東西沒,這2個單位的 值是畫素,前者代表 view的左邊緣和view內容左邊緣的距離。 後者代表 view上邊緣和view內容上邊緣的距離。

5.使用動畫來實現view的滑動 有什麼後果?

答:實際上view動畫 是對view的表面ui 也就是給使用者呈現出的視覺效果 來做的移動,動畫本身並不能移動view的真正位置。屬性動畫除外。動畫播放結束以後,view最終還是會

回到自己的位置的,。當然了你可以設定fillafter 屬性 來讓動畫播放結束以後 view表象停留在 變化以後的位置。所以這會帶來一個很嚴重的後果。比如你的button在螢幕的左邊,

你現在用個動畫 並且設定了fillafter屬性讓他去了右邊。你會發現 點選右邊的button 沒有click事件觸發,但是點選左邊的 卻可以觸發,原因就是右邊的button 只是view的表象,

真正的button 還在左邊沒有動過。你一定要這麼做的話 可以提前在右邊button移動後的位置放一個新的button,當你動畫執行結束以後  把右邊的enable 左邊的讓他gone就可以了。

這麼做就可以規避上述問題。

6.讓view滑動總共有幾種方式,分別要注意什麼?都適用於那些場景?

答:總共有三種:

a:scrollto,scrollby。這種是最簡單的,但是隻能滑動view的內容 不可以滑動view本身。

b:動畫。動畫可以滑動view內容,但是注意非屬性動畫 就如我們問題5說的內容 會影響到互動,使用的時候要多注意。不過多數複雜的滑動效果都是屬性動畫來完成的,屬於大殺器級別、

c:改變佈局引數。這種最好理解了,無非是動態的通過java程式碼來修改 margin等view的引數罷了。不過用的比較少。我本人不怎麼用這種方法。

7.Scroller是幹嘛的?原理是什麼?

答:Scroller就是用於 讓view有滑動漸變效果的。用法如下:

其實上述程式碼 很多人應該都能搜到。我們這裡主要講一下 他的原理。

8.view的滑動漸變效果總共有幾種方法?

答:三種,第一種是scroller 也是使用最多的。問題7裡有解釋。還有一種就是動畫,動畫我就不多說了,不屬於本文範疇。最後一種也是我們經常使用的就是用handler ,每隔一個時間間隔 來更新view的狀態。

程式碼不寫了很簡單。 自行體會。

9.view的事件傳遞機制 如何用虛擬碼來表示?

答:

10.view的onTouchEvent,OnClickListerner和OnTouchListener的onTouch方法 三者優先順序如何?

答:onTouchListener優先順序最高,如果onTouch方法返回 false ,那onTouchEvent就被呼叫了,返回true 就不會被呼叫。至於onClick 優先順序最低。

11.點選事件的傳遞順序如何?

答:Activity-Window-View。從上到下依次傳遞,當然瞭如果你最低的那個view onTouchEvent返回false 那就說明他不想處理 那就再往上拋,都不處理的話

最終就還是讓Activity自己處理了。舉個例子,pm下發一個任務給leader,leader自己不做 給架構師a,小a也不做 給程式設計師b,b如果做了那就結束了這個任務。

b如果發現自己搞不定,那就找a做,a要是也搞不定 就會不斷向上發起請求,最終可能還是pm做。

12.事件分為幾個步驟?

答:down事件開頭,up事件結尾,中間可能會有數目不定的move事件。

13.ViewGroup如何對點選事件分發?

答:

14.如果某個view 處理事件的時候 沒有消耗down事件 會有什麼結果?

答:假如一個view,在down事件來的時候 他的onTouchEvent返回false, 那麼這個down事件 所屬的事件序列 就是他後續的move 和up 都不會給他處理了,全部都給他的父view處理。

15.如果view 不消耗move或者up事件 會有什麼結果?

答:那這個事件所屬的事件序列就消失了,父view也不會處理的,最終都給activity 去處理了。

16.ViewGroup 預設攔截事件嗎?

答:預設不攔截任何事件,onInterceptTouchEvent返回的是false。

17.一旦有事件傳遞給view,view的onTouchEvent一定會被呼叫嗎?

答:是的,因為view 本身沒有onInterceptTouchEvent方法,所以只要事件來到view這裡 就一定會走onTouchEvent方法。

並且預設都是消耗掉,返回true的。除非這個view是不可點選的,所謂不可點選就是clickable和longgclikable同時為fale

Button的clickable就是true 但是textview是false。

18.enable是否影響view的onTouchEvent返回值?

答:不影響,只要clickable和longClickable有一個為真,那麼onTouchEvent就返回true。

19.requestDisallowInterceptTouchEvent 可以在子元素中干擾父元素的事件分發嗎?如果可以,是全部都可以干擾嗎?

答:肯定可以,但是down事件干擾不了。

20.dispatchTouchEvent每次都會被呼叫嗎?

答:是的,onInterceptTouchEvent則不會。

21.滑動衝突問題如何解決 思路是什麼?

答。要解決滑動衝突 其實最主要的就是有一個核心思想。你到底想在一個事件序列中,讓哪個view 來響應你的滑動?比如 從上到下滑,是哪個view來處理這個事件,從左到右呢?

用業務需求 來想明白以後 剩下的 其實就很好做了。核心的方法 就是2個 外部攔截也就是父親攔截,另外就是內部攔截,也就是子view攔截法。 學會這2種 基本上所有的滑動衝突

都是這2種的變種,而且核心程式碼思想都一樣。

外部攔截法:思路就是重寫父容器的onInterceptTouchEvent即可。子元素一般不需要管。可以很容易理解,因為這和android自身的事件處理機制 邏輯是一模一樣的

內部攔截法:內部攔截法稍微複雜一點,就是事件到來的時候,父容器不管,讓子元素自己來決定是否處理。如果消耗了 就最好,沒消耗 自然就轉給父容器處理了。

子元素程式碼:

父親容器程式碼也要修改一下,其實就是保證父親別攔截down:

相關文章