編輯:關於android開發
轉載於:http://blog.csdn.net/yuanzeyao/article/details/38025165
在前一篇文章中,我主要講解了Android源碼中的Touch事件的傳遞過程,現在我想使用一個demo以及一個實例來學習一下Andorid中的Touch事件處理過程。
在Android系統中,和Touch事件分發和處理緊密相關的三個函數如下:
(1) public boolean dispatchTouchEvent(MotionEvent ev)
(2) public boolean onInterceptTouchEvent(MotionEvent ev)
(3) public boolean onTouchEvent(MotionEvent event)
這三個方法我在前一篇文章中都對他們的源碼進行了分析:方法1主要是對Touch事件進行分發,方法2主要是對Touch事件進行攔截,方法3是對Touch事件進行處理
這三個方法主要存在於ViewGroup,View,Activity中,具體情況如下圖:
ViewGroup View Activity dispatchTouchEvent 有 有 有 onInterceptTouchEvent 有 無 無 onTouchEvent 有 有 有下面我們就使用一個demo來看看這些方法的執行流程:
自定義一個類:MyLayoutFirst.java
[java] view plain copy print?
自定義一個類;MyLayoutSecond.java
[java] view plain copy print?
加入到main_layout.xml中
[html] view plain copy print?
MainActivity中加入onTouchEvent方法
[java] view plain copy print?
最後就一個工具類,用來將事件id轉換為字符串。
[java] view plain copy print?
運行效果如圖:
第一中情況:
MainActivity
MyLayoutFirst
MyLayoutSecond
dispatchTouchEvent
super.dispatchTouchEvent
super.dispatchTouchEvent
super.dispatchTouchEvent
onInterceptTouchEvent
--
super.onInterceptTouchEvent(ev)
super.onInterceptTouchEvent(ev)
onTouchEvent
super.onTouchEvent
super.onTouchEven
super.onTouchEvent
運行結果:
其中藍色部分是MyLayoutSecond.Java ,紅色部分是MyLayoutFirst.java
現在我點擊一下藍色部分:運行結果如圖:
從圖中可以看出,事件最先被Activity捕獲,然後分發給 MyLayoutFirst,MyLayoutFirst首先調用自身的onInterceptTouchEvent判斷是否將該事件攔截,由於默認返回是false,所以沒有攔截,從而事件分發給了MyLayoutSecond,MyLayoutSecond同樣通過dispatchTouchEvent分發出去,分發出去之前同樣檢查是否被攔截,默認都是沒有被攔截的,但是由於MyLayoutSecond是沒有子視圖的,所有最終事件有自己處理,調用自身的onTouchEvent方法,由於該方法默認返回的是false,所以認為此事件是沒有被消費掉的,繼續傳遞到了MyLayoutFirst中,同樣也沒有消費這個事件,最終傳遞到了Mainactivity,繼續往後看發現後面的ACTION_MOVE和ACTION_UP並沒有傳入MyLayoutFirst和MyLayoutSecond,這是因為一旦某一個事件沒有被處理,後面的事件是不會被分發的。所以ACTION_MOVE和ACTION_UP直接被MainActivity處理掉了。
下面再看第二種情況:
MainActivity
MyLayoutFirst
MyLayoutSecond
dispatchTouchEvent
super.dispatchTouchEvent
super.dispatchTouchEvent
super.dispatchTouchEvent
onInterceptTouchEvent
--
true
super.onInterceptTouchEvent(ev)
onTouchEvent
super.onTouchEvent
super.onTouchEvent
super.onTouchEvent
運行結果如下:
從圖中可以看出,事件傳遞到了MyLayoutFirst後沒有分發到MyLayoutSecond,直接調用自身的onTouchEvent,由於返回的是false,導致事件沒有消費,最終傳遞給了MainActivity,
而且後續事件也沒有傳遞到MyLayoutFirst和MyLayoutSecond,直接被MainActivity處理
第三種情況:
MainActivity
MyLayoutFirst
MyLayoutSecond
dispatchTouchEvent
super.dispatchTouchEvent
super.dispatchTouchEvent
super.dispatchTouchEvent
onInterceptTouchEvent
--
true
super.onInterceptTouchEvent(ev)
onTouchEvent
super.onTouchEvent
true
super.onTouchEvent
運行結果:
和情況二不同的是MyLayoutFirst的onTouchEvent返回了true,也就是說MyLayoutFirst消費了此事件,所以ACTION_DOWN也沒有再傳給MainActivity,並且ACTION_MOVE和ACTION_UP
均傳給了MyLayoutFirst
第四中情況:
MainActivity
MyLayoutFirst
MyLayoutSecond
dispatchTouchEvent
super.dispatchTouchEvent
super.dispatchTouchEvent
super.dispatchTouchEvent
onInterceptTouchEvent
--
super.onInterceptTouchEvent(ev)
super.onInterceptTouchEvent(ev)
onTouchEvent
super.onTouchEvent
super.onTouchEven
true
運行結果:
發現所有的事件都是傳遞到了MyLayoutSecond後被消費了
其實還有很多其他組合方式,大家如果又興趣可以自己嘗試改變每個函數的返回值,查看打印結果,這裡我就不一一列舉了。。。。。
最後我會提供一個小demo演示如何解決滑動沖突,背景如下:
一個ViewPager裡面包含兩個Framgent,有一個Fragment裡面有一個HorizontalListView ,如何滑動沖突?
我就貼出關鍵代碼吧
[java] view plain copy print?
加入這段代碼就可以避免滑動沖突了,至於為什麼大家可以參考我的前以前文章《Android Touch 事件傳遞機制詳解 上》 這兩個demo的例子我均會上傳下載的
(轉)根據ImageView的大小來壓縮Bitmap,避免OOM,imageviewoom本文轉載於:http://www.cnblogs.com/tianzhijiex
Hive 1.2.1&Spark&Sqoop安裝指南Hive 1.2.1&Spark&Sqoop安裝指南.pdf目錄目錄11.前言12.約定23.服務端口
百度地圖開發的學習(二)——地圖定位,百度地圖定位是地圖開發的必經重要的環節,我也在不斷學習中,就自己了解寫一下這些。 一、配置 1.百度的定位是有自己jar包和so文件
android編譯系統學習,android編譯學習近日接手了後續android新平台項目搭建的任務。 本文內容基於sprd公司提供的android5.1源碼。 一、一般的