Android 事件分發(fā)機(jī)制

基礎(chǔ)知識點:

對于觸屏手機(jī)诲祸,我們在上面進(jìn)行的任何點擊、滑動掀序,也就是觸屏(Touch)活動帆焕,都會生成被封裝到一種叫MotionEvent的事件里,Android系統(tǒng)用一下六種類型來描述用戶的touch事件類型

ACTION_DOWN(按下)

ACTION_MOVE(屏幕滑動)

ACTION_UP(離開屏幕)

ACTION_POINTER_DOWN(多點觸屏?xí)r產(chǎn)生森枪,暫不講解)

ACTION_POINTER_UP(多點觸屏?xí)r產(chǎn)生视搏,暫不講解)

ACTION_CANCEL

MotionEvent里面包含豐富的數(shù)據(jù)信息,包括:Touch的位置(Touch location)审孽,Touch的觸點數(shù)(也即手指數(shù))县袱,Touch的時刻等等

一個完整的手勢(gesture)是以action_down開始,以action_up結(jié)束

事件流:action_down--->action_move--->action_move--->action_move.....--->action_up(中間的action_move事件是否發(fā)生取決于手勢是否發(fā)生移動)

想想你平常在桌面點擊打開app和頁面切換滑動時激發(fā)的事件流是否有所不同佑力?

事件的分發(fā)式散,攔截,響應(yīng)的機(jī)制(關(guān)鍵字:分發(fā)打颤,攔截暴拄,響應(yīng),消費)

想象:想象一下貪官貪污的一種情況:在某某貧困縣编饺,每年國家都會給予一定的資金補(bǔ)助(分發(fā)過程)乖篷,這筆錢(touch事件)經(jīng)過省政府(根布局),市政府(父布局)都沒人去貪污它(即沒人去攔截它)透且,那么這錢就繼續(xù)往下分發(fā)撕蔼,到了縣政府這里來,此時某某縣大領(lǐng)導(dǎo)(子view)想吃下這筆錢秽誊,那么他就不讓這錢逃過他的手了鲸沮,所以他進(jìn)行了攔截,攔截下來后锅论,就要對這錢進(jìn)行“處理”呀讼溺,這時就進(jìn)行了響應(yīng)和消費,以后只要這官不被抓最易,那么每年國家撥下來的資金都分發(fā)到他這里就被攔截及消費了怒坯。當(dāng)然還有另外一種情況(現(xiàn)實不大可能發(fā)生),就是整個過程沒有人貪污藻懒,那么錢就一步一步分發(fā)下去敬肚,發(fā)到縣以后,這些年貧困縣發(fā)展起來了束析,決定不要這筆錢了(響應(yīng)但不消費)艳馒,所以就把錢還給市政府,市政府也決定不要這錢(響應(yīng)但不消費),就又把錢交給省政府了

事件分發(fā)流程:從父布局到子布局:Activity--->RootView--->ViewGroup1--->ViewGroup1的子ViewGroup2 ---> Target View

事件的響應(yīng)流程:從子布局到父布局:Target View--->ViewGroup2--->ViewGroup1--->RootView--->activity



幾個規(guī)則:

所有的事件從activity的dispatchTouchevent()函數(shù)開始弄慰,從父布局到子布局往下分發(fā)第美,當(dāng)然每個布局在任何事件傳到它那里后都可進(jìn)行攔截

所有的事件順著界面布局層次往下分發(fā),分發(fā)完就回溯(上面的分發(fā)和響應(yīng)流程)陆爽,這一過程中一旦出現(xiàn)了消費什往,流程就停在消費的view那一層,view必須把a(bǔ)ction_down事件消費掉后慌闭,后續(xù)的這個手勢的其他的事件才會傳到這個view别威。

如果整個過程沒有view想消費這個事件,那么最終的回溯的結(jié)束點就是activity的onTouchEvent()驴剔。

幾個涉及的重要方法(view或viewgroup里的方法):

public boolean dispatchTouchEvent(Motion ev):事件分發(fā)方法省古,把當(dāng)前事件分發(fā)給下一子布局,是一個遞歸的調(diào)用函數(shù)丧失,返回true則表示事件被處理

public boolean onInterceptTouchEvent(MotionEvent event):事件攔截方法,根據(jù)事件類型進(jìn)行攔截豺妓,比如一個scrollview想攔截action_move這個事件,返回true則表示進(jìn)行了攔截

public boolean onTouchEvent(MotionEvent event):事件響應(yīng)處理方法布讹,可以在方法中把事件消費了琳拭,也可不消費,那么就回溯給上級去響應(yīng)和處理描验,返回true則表示事件被消費

整個分發(fā)和響應(yīng)過程的規(guī)則可以用以下的偽代碼(摘自《Android開發(fā)藝術(shù)探索》)表示:

public boolean dispatchTouchEvent(MotionEvent event){

? ? ?boolean consume=false;

? ? ?if(onInterceptTouchEvent(event)){

? ? ? ? ? ?consume=onTouchEvent(event);

? ? ?} else {?

? ? ? ? ? ?consume=ChildView.dispatchTouchEvent(event);

? ? ?}

? ? ?return consume;

}

以下根據(jù)實例講述過程:本截圖引用自全英文檔http://trinea.github.io/download/pdf/android/PRE_andevcon_mastering-the-android-touch-system.pdf



講解:此布局是在frameLayout里面嵌套一個普通的view白嘁,當(dāng)你按下的時候,會觸發(fā)down事件膘流,事件就從activity出發(fā)絮缅,由于此時沒有任何的布局對此感興趣(即沒攔截和消費),那么分發(fā)完后回溯會activity的onTouchEvent睡扬,后續(xù)發(fā)生的move和up事件盟蚣,這時Android系統(tǒng)會這么認(rèn)為:既然你整個布局所有組件連按下去的事件都不感興趣,后續(xù)發(fā)生的事件肯定也是不感興趣卖怜,所以事件move和up都不往下進(jìn)行分發(fā)和回溯了屎开,直接在activity自己調(diào)用onTouchEvent去處理


講解:此布局是在frameLayout里面嵌套一個button,當(dāng)你按下的時候马靠,會觸發(fā)down事件奄抽,事件就從activity出發(fā),由于此時button對此事件感興趣甩鳄,那么button的onTouchEvent就會對此進(jìn)行消費逞度,事件被消費后就不會再回溯了,后續(xù)發(fā)生的move和up事件妙啃,button也是感興趣档泽,也進(jìn)行了消費俊戳,所以整個流程就只走到了button的onTouchEvent方法


講解:此布局是在Scrollview里面嵌套一個button,當(dāng)你按下的時候馆匿,會觸發(fā)down事件抑胎,事件就從activity出發(fā),由于此時button對此事件感興趣渐北,而scrollView對此事件不感興趣阿逃,那么button的onTouchEvent就會對此進(jìn)行消費,事件被消費后就不會再回溯了赃蛛,后續(xù)發(fā)生的move和up事件恃锉,scrollview和button都感興趣,但是由于scrollview先拿到事件呕臂,進(jìn)行攔截和消費破托,所以事件流就沒走到button那里,那為什么還會走回activity的onTouchEvent呢诵闭,scrollview進(jìn)行攔截炼团,但不進(jìn)行消費澎嚣,也就是scrollview的onTouchEvent返回值是false疏尿,所以才會回溯給activity。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末易桃,一起剝皮案震驚了整個濱河市褥琐,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌晤郑,老刑警劉巖敌呈,帶你破解...
    沈念sama閱讀 217,907評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異造寝,居然都是意外死亡磕洪,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評論 3 395
  • 文/潘曉璐 我一進(jìn)店門诫龙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來析显,“玉大人,你說我怎么就攤上這事签赃」纫欤” “怎么了?”我有些...
    開封第一講書人閱讀 164,298評論 0 354
  • 文/不壞的土叔 我叫張陵锦聊,是天一觀的道長歹嘹。 經(jīng)常有香客問我,道長孔庭,這世上最難降的妖魔是什么尺上? 我笑而不...
    開封第一講書人閱讀 58,586評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上怎抛,老公的妹妹穿的比我還像新娘仰税。我一直安慰自己,他們只是感情好抽诉,可當(dāng)我...
    茶點故事閱讀 67,633評論 6 392
  • 文/花漫 我一把揭開白布陨簇。 她就那樣靜靜地躺著,像睡著了一般迹淌。 火紅的嫁衣襯著肌膚如雪河绽。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,488評論 1 302
  • 那天唉窃,我揣著相機(jī)與錄音耙饰,去河邊找鬼。 笑死纹份,一個胖子當(dāng)著我的面吹牛苟跪,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蔓涧,決...
    沈念sama閱讀 40,275評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼件已,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了元暴?” 一聲冷哼從身側(cè)響起篷扩,我...
    開封第一講書人閱讀 39,176評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎茉盏,沒想到半個月后鉴未,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,619評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡鸠姨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,819評論 3 336
  • 正文 我和宋清朗相戀三年铜秆,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片讶迁。...
    茶點故事閱讀 39,932評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡连茧,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出添瓷,到底是詐尸還是另有隱情梅屉,我是刑警寧澤,帶...
    沈念sama閱讀 35,655評論 5 346
  • 正文 年R本政府宣布鳞贷,位于F島的核電站坯汤,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏搀愧。R本人自食惡果不足惜惰聂,卻給世界環(huán)境...
    茶點故事閱讀 41,265評論 3 329
  • 文/蒙蒙 一疆偿、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧搓幌,春花似錦杆故、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,871評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至拐揭,卻和暖如春撤蟆,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背堂污。 一陣腳步聲響...
    開封第一講書人閱讀 32,994評論 1 269
  • 我被黑心中介騙來泰國打工家肯, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人盟猖。 一個月前我還...
    沈念sama閱讀 48,095評論 3 370
  • 正文 我出身青樓讨衣,卻偏偏與公主長得像,于是被迫代替她去往敵國和親式镐。 傳聞我的和親對象是個殘疾皇子反镇,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,884評論 2 354

推薦閱讀更多精彩內(nèi)容