Android -- TouchEvent的分发和截获方式
Android系統(tǒng)中的每個ViewGroup的子類都具有下面三個和TouchEvent處理密切相關(guān)的方法:
public boolean dispatchTouchEvent(MotionEvent ev) // 這個方法用來分發(fā)TouchEventpublic boolean onInterceptTouchEvent(MotionEvent ev) //這個方法用來攔截TouchEventpublic boolean onTouchEvent(MotionEvent ev) //這個方法用來處理TouchEvent注意:不是所有的View的子類,很多教程都說的是所有的View的子類,只有可以向里面添加View的控件才需要分發(fā),比如TextView它本身就是最小的view了,所以不用再向它的子視圖分發(fā)了,它也沒有子視圖了,所以它沒有dispatch和Intercept,只有touchEvent。
onInterceptTouchEvent(MotionEvent?ev)方法是GroupView控件中特有的一個方法,我們可以實現(xiàn)這個方法來截獲所有的窗口點擊事件來根據(jù)事件的不同來對子控件或自身分發(fā)事件觸發(fā)。覆蓋這個方法時需要小心注意,因為它和View.onTouchEvent(MotionEvent)有著復(fù)雜的關(guān)系,我們使用是需要和View.onTouchEvent(MotionEvent)一同實現(xiàn)來達到正確的結(jié)果,事件觸發(fā)順序如下:
1.你首先會在該方法中得到一個down事件。
??????? 2.這個down事件會被得到處理,要么在這個GroupView中子控件的onTouchEvent()方法中,要么在GroupView自身的onTouchEvent()方法中。當我們在onTouchEvent()方法返回值中返回true的話,將會繼續(xù)看到后續(xù)的觸發(fā)事件(move、up等),要注意的是當我們在GroupView的onTouchEvent()事件返回值中返回false的話,該方法將不再捕獲后續(xù)的(move up)事件。
3.如果在該方法返回值中返回false,down事件將根據(jù)控件樹結(jié)構(gòu)從根節(jié)點向目標子控件的onTouchEvent()方法分發(fā)。
4.如果在該方法返回值中返回true,那么你的子控件將獲取不到任何點擊事件。
? 為證明上面所說的順序特點,下面通過測試代碼來觀察觀察:
public class MainActivity extends Activity {Group1 group1;Group2 group2;MyTextView myTv;/** Called when the activity is first created. */@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);//--group1//----|//-------group2//---------|//------------myTv group1 = new Group1(this);group2 = new Group2(this);myTv = new MyTextView(this);group2.addView(myTv, new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT));group1.addView(group2, new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT));setContentView(group1);}}分別重寫Group1和Group2的onInterceptTouchEvent和onTouchEvent方法,重寫MyTextView的onTouchEvent方法,最終得到的控件層次結(jié)構(gòu)如下:
1.在默認返回值情況下logcat輸出如下:
測試后可知默認情況下和所有方法返回值為false的結(jié)果一致,down事件的捕獲順序onInterceptTouchEvent先于onTouchEvent,由于onTouchEvent返回值為false,down事件沒被消化,后續(xù)的move和up事件沒有出現(xiàn),同時逆序返回到父控件的onTouchEvent方法來捕獲,如下圖所示:
2.所有onTouchEvent返回值為true情況下logcat輸出如下:
輸出結(jié)果可以看出子控件MyTextView消化了down事件,后續(xù)的move和up事件正常捕獲,由于down事件被消化,上層的onTouchEvent方法不執(zhí)行,如下圖所示:(三箭頭分別指down、move、up事件)
既然如此,如果MyTextView中onTouchEvent方法返回為false,而group1和group2的onTouchEvent方法返回true的結(jié)果自然也就如下圖的順序了:
測試輸出結(jié)果證明了這一猜測順序,
3.當某個GroupView中的onInterceptTouchEvent方法返回值為true情況下logcat輸出如下(如group2):
如果在該方法返回值中返回true,那么子控件將獲取不到任何點擊事件,轉(zhuǎn)而向自身的onTouchEvent方法轉(zhuǎn)發(fā),如下圖所示:
如果onTouchEvent方法返回值都為true,那么根據(jù)規(guī)律結(jié)果就如下圖順序觸發(fā):
最后logcat的結(jié)果證實了這一猜測,
根據(jù)這一順序規(guī)律我們便可復(fù)寫GroupView中的onInterceptTouchEvent來控制事件的響應(yīng)者。
我是天王蓋地虎的分割線 ? ? ? ? ??
本文轉(zhuǎn)自我愛物聯(lián)網(wǎng)博客園博客,原文鏈接:http://www.cnblogs.com/yydcdut/p/3907743.html,如需轉(zhuǎn)載請自行聯(lián)系原作者
總結(jié)
以上是生活随笔為你收集整理的Android -- TouchEvent的分发和截获方式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Cesium学习笔记(五):3D 模型
- 下一篇: Android图片剪裁库