Android View事件傳遞過程

了解Android View事件的傳遞過程枚荣,是編寫復雜控件、解決ScrollView嵌套等問題的基礎澄成。
以touch事件為例暖哨,和其相關的回調函數(shù)有:

  • dispatchTouchEvent肌厨,進行事件的分發(fā)
  • onInterceptTouchEvent培慌,ViewGroup對事件進行攔截
  • onTouchEvent,響應具體的touch事件
    下面通過一個簡單的demo來觀察這三個函數(shù)是如何調用的柑爸。
    demo包括兩部分吵护,CustomViewGroup和CustomView,通過重寫上面的三個方法,在其中輸出日志來觀察調用過程馅而。

CustomViewGroup代碼如下:

public class CustomViewGroup extends FrameLayout {
    private static final String TAG = "CustomViewGroup";

    public CustomViewGroup(Context context) {
        super(context);
    }

    public CustomViewGroup(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CustomViewGroup(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.d(TAG, "onTouchEvent");
        return super.onTouchEvent(event);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        Log.d(TAG, "onInterceptTouchEvent");
        return super.onInterceptTouchEvent(ev);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        Log.d(TAG, "dispatchTouchEvent");
        return super.dispatchTouchEvent(ev);
    }
}

CustomView代碼如下:

public class CustomView extends View {

    private static final String TAG = "CustomView";
    public CustomView(Context context) {
        super(context);
    }

    public CustomView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public CustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.d(TAG, "onTouchEvent");
        return super.onTouchEvent(event);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        Log.d(TAG, "dispatchTouchEvent");
        return super.dispatchTouchEvent(event);
    }
}

布局文件

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.xiaomi.shop.testdemo.MainActivity">

    <com.xiaomi.shop.testdemo.view.event.CustomViewGroup
        android:background="#ff0"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <com.xiaomi.shop.testdemo.view.event.CustomView
            android:background="#f00"
            android:layout_width="200dp"
            android:layout_height="200dp" />
    </com.xiaomi.shop.testdemo.view.event.CustomViewGroup>
</FrameLayout>

運行demo祥诽,界面如下:

demo屏幕截圖

紅色區(qū)域為CustomView,黃色區(qū)域為CustomViewGroup
點擊紅色區(qū)域瓮恭,看到日志輸出如下:

05-08 11:44:55.304 12481-12481/com.xiaomi.shop.testdemo D/CustomViewGroup: dispatchTouchEvent
05-08 11:44:55.304 12481-12481/com.xiaomi.shop.testdemo D/CustomViewGroup: onInterceptTouchEvent
05-08 11:44:55.304 12481-12481/com.xiaomi.shop.testdemo D/CustomView: dispatchTouchEvent
05-08 11:44:55.304 12481-12481/com.xiaomi.shop.testdemo D/CustomView: onTouchEvent
05-08 11:44:55.305 12481-12481/com.xiaomi.shop.testdemo D/CustomViewGroup: onTouchEvent

1. 默認情況

dispatchTouchEvent雄坪,進行事件的分發(fā)
onInterceptTouchEvent,ViewGroup對事件進行攔截屯蹦,默認返回false维哈,即不攔截
onTouchEvent,響應具體的touch事件登澜,默認返回false阔挠,即無響應
由上面的日志輸出可以看出,默認情況下脑蠕,函數(shù)的調用順序為:
ViewGroup.dispatchTouchEvent
ViewGroup.onInterceptTouchEvent
View.dispatchTouchEvent
View.onTouchEvent
ViewGroup.onTouchEvent
需要注意的是购撼,上面的日志只在手指點到紅色區(qū)域后輸出一次,手指滑動時谴仙,并沒有新的日志輸出迂求。因為CustomView的onTouchEvent返回的false,所以CustomViewGroup認為CustomView不處理touch事件狞甚,所以后續(xù)的點擊事件便不再向其分發(fā)锁摔。如何沒有子View處理touch事件的話,那么就會自己處理哼审,所以最后會調用到CustomViewGroup的onTouchEvent谐腰。

2. CustomView的onTouchEvent返回true

下面把CustomView的onTouchEvent的返回值改為true,表示處理touch事件涩盾,此時的日志輸出為:

05-08 15:27:05.354 24788-24788/com.xiaomi.shop.testdemo D/CustomViewGroup: dispatchTouchEvent
05-08 15:27:05.354 24788-24788/com.xiaomi.shop.testdemo D/CustomViewGroup: onInterceptTouchEvent
05-08 15:27:05.354 24788-24788/com.xiaomi.shop.testdemo D/CustomView: dispatchTouchEvent
05-08 15:27:05.355 24788-24788/com.xiaomi.shop.testdemo D/CustomView: onTouchEvent
05-08 15:27:05.380 24788-24788/com.xiaomi.shop.testdemo D/CustomViewGroup: dispatchTouchEvent
05-08 15:27:05.380 24788-24788/com.xiaomi.shop.testdemo D/CustomViewGroup: onInterceptTouchEvent
05-08 15:27:05.380 24788-24788/com.xiaomi.shop.testdemo D/CustomView: dispatchTouchEvent
05-08 15:27:05.380 24788-24788/com.xiaomi.shop.testdemo D/CustomView: onTouchEvent
...

這次跟前面有兩個不同十气,首先是點擊和滑動都會輸出日志,因為CustomView對touch事件感興趣春霍,所以后續(xù)的事件都會傳遞給它砸西。另外這次沒有調用CustomViewGroup的onTouchEvent函數(shù),這是因為子View處理了touch事件址儒,所以自己便不再處理芹枷。

3. 打開事件攔截

將CustomViewGroup的onInterceptTouchEvent函數(shù)的返回值改為true,啟動事件攔截莲趣。在紅色區(qū)域點擊滑動鸳慈,日志輸出如下:

05-08 15:35:26.393 8556-8556/com.xiaomi.shop.testdemo D/CustomViewGroup: dispatchTouchEvent
05-08 15:35:26.394 8556-8556/com.xiaomi.shop.testdemo D/CustomViewGroup: onInterceptTouchEvent
05-08 15:35:26.394 8556-8556/com.xiaomi.shop.testdemo D/CustomViewGroup: onTouchEvent

CustomView的任何函數(shù)都沒有調用。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末喧伞,一起剝皮案震驚了整個濱河市走芋,隨后出現(xiàn)的幾起案子绩郎,更是在濱河造成了極大的恐慌,老刑警劉巖翁逞,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件肋杖,死亡現(xiàn)場離奇詭異,居然都是意外死亡挖函,警方通過查閱死者的電腦和手機状植,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來挪圾,“玉大人浅萧,你說我怎么就攤上這事≌芩迹” “怎么了洼畅?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長棚赔。 經(jīng)常有香客問我帝簇,道長,這世上最難降的妖魔是什么靠益? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任丧肴,我火速辦了婚禮,結果婚禮上胧后,老公的妹妹穿的比我還像新娘芋浮。我一直安慰自己,他們只是感情好壳快,可當我...
    茶點故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布纸巷。 她就那樣靜靜地躺著,像睡著了一般眶痰。 火紅的嫁衣襯著肌膚如雪瘤旨。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天竖伯,我揣著相機與錄音存哲,去河邊找鬼。 笑死七婴,一個胖子當著我的面吹牛祟偷,可吹牛的內容都是我干的。 我是一名探鬼主播打厘,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼修肠,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了婚惫?” 一聲冷哼從身側響起氛赐,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎先舷,沒想到半個月后艰管,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡蒋川,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年牲芋,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片捺球。...
    茶點故事閱讀 38,064評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡缸浦,死狀恐怖,靈堂內的尸體忽然破棺而出氮兵,到底是詐尸還是另有隱情裂逐,我是刑警寧澤,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布泣栈,位于F島的核電站卜高,受9級特大地震影響,放射性物質發(fā)生泄漏南片。R本人自食惡果不足惜掺涛,卻給世界環(huán)境...
    茶點故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望疼进。 院中可真熱鬧薪缆,春花似錦、人聲如沸伞广。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽赔癌。三九已至诞外,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間灾票,已是汗流浹背峡谊。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留刊苍,地道東北人既们。 一個月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像正什,于是被迫代替她去往敵國和親啥纸。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,802評論 2 345

推薦閱讀更多精彩內容