Android開發(fā)藝術(shù)探索筆記——View(二)

Android開發(fā)藝術(shù)探索筆記——View(二)

View的事件分發(fā)機制

學(xué)習(xí)資料:
1.Understanding Android Input Touch Events System Framework
2.Managing Touch Events in a ViewGroup
3.Android事件傳遞機制
4.Input Events
5.Mastering the Android Touch System
6.MotionEvent

MotionEvent(運動事件)的傳遞規(guī)則

用戶每次觸摸屏幕都被包裝成了MotionEvent(運動事件)對象恶守。

屬性有:

  • 動作碼(action code),如ACTION_DOWN,ACTION_UP等等,用于描述用戶當(dāng)前的動作。
  • 觸摸的橫縱坐標岔冀。
  • 其它信息必指,如壓力,大小以及方向等等蜜笤。

View的事件分發(fā),就是對MotionEvent事件的分發(fā)過程惕味。

事件分發(fā)的三個重要方法:

//用于分發(fā)事件(dispatch touch event),要么將事件向下傳遞到目標View楼誓,要么交由自己處理。
//返回true表示自己處理
public boolean dispatchTouchEvent (MotionEvent event)


//用于攔截事件(intercept touch event),ViewGroup中有名挥,View中沒有這個方法疟羹。
public boolean onInterceptTouchEvent (MotionEvent event)


//用于處理事件
public boolean onTouchEvent (MotionEvent event)

三個方法的關(guān)系可用如下偽代碼描述:

public boolean dispatchTouchEvent(MotionEvent ev){
   boolean consume = false;
   if(onInterceptTouchEvent(ev)){
     consume = true;
   }else{
     consume = child.dispatchTouchEvent(ev);
   }
   return consume;
}
viewTouchEvent

View的onTouchListener的優(yōu)先級比onTouchEvent方法的高。

運動事件的傳遞順序:

Activity-->Window-->View

下面是將ViewdispatchTouchEvent()方法設(shè)置斷點后禀倔,點擊ImageView的調(diào)試過程:

viewTouchEvent

能清楚地看到事件的傳遞過程和順序榄融。

若View的onTouchEvent()方法返回false,則會調(diào)用它的父View的onTouchEvent()方法救湖,依此類推愧杯,若調(diào)用順序上的所有View都不處理這個事件,則這個事件會最終傳遞給Activity的onTouchEvent()方法鞋既。

View的事件分發(fā)機制類似于互聯(lián)網(wǎng)公司的工作流程:

 新任務(wù):
 CEO-->產(chǎn)品經(jīng)理-->CTO-->開發(fā)小組組長-->程序員
 
 由上至下一級一級分發(fā)任務(wù)(dispatchTouchEvent)力九,如果是自己的任務(wù)(onInterceptTouchEvent)
 ,則攔截自己處理(onTouchEvent)邑闺,反之畏邢,則交由下級分發(fā)(child.dispatchTouchEvent)。
 
 如果事情搞不定检吆,就一級一級向上拋(parent.onTouchEvent):
 程序員-->開發(fā)組長-->CTO-->產(chǎn)品經(jīng)理-->CEO
 

事件傳遞機制的一些結(jié)論:

  • 1.事件序列:從手指接觸屏幕到手指離開屏幕的過程舒萎,ACTION_DOWN-->ACTION_MOVE-->...-->ACTION_MOVE-->ACTION_UP
  • 2.一個事件序列只能被一個View攔截且消費。
  • 3.ViewGroup默認不攔截事件蹭沛。源碼中ViewGroup的onInterceptTouchEvent()方法默認返回false
  • 4.View沒有onInterceptTouchEvent()方法
  • 5.事件傳遞是由外向內(nèi)(由上至下)的臂寝。事件先傳遞給父元素,然后再由父元素分發(fā)給子元素摊灭。通過 requestDisallowInterceptTouchEvent()方法可以在子元素中干預(yù)父元素的事件分發(fā)過程咆贬。

事件分發(fā)源碼解析

Activity對事件的分發(fā)過程

  • 1.點擊事件首先傳遞給Activity,然后由ActivitydispatchTouchEvent()方法進行事件的分發(fā)。Activity會將事件交由window進行分發(fā)帚呼。
//Activity源碼
 ...
 /*
  * Activity的dispatchTouchEvent方法
  */
 public boolean dispatchTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            onUserInteraction();
        }
        //Activity交由window進行事件分發(fā)
        if (getWindow().superDispatchTouchEvent(ev)) {
            return true;
        }
        return onTouchEvent(ev);
    }
  • 2.Window將事件傳遞給DecorView(即ContentView的父View掏缎,可通過Activity.getWindow().getDecorView()方法獲取)。而Window類是抽象類煤杀,superDispatchTouchEvent()方法是抽象方法眷蜈。
//Window類是抽象類
public abstract class Window {
...
//window的superDispatchTouchEvent方法是抽象方法
public abstract boolean superDispatchTouchEvent(MotionEvent event);
...
}

而PhoneWindow類是Window類的唯一實現(xiàn)類。


public class PhoneWindow extends Window implements MenuBuilder.Callback {
...
  @Override
    public boolean superDispatchTouchEvent(MotionEvent event)       { 
    //PhoneWindow直接將事件交友DecorView處理
    return mDecor.superDispatchTouchEvent(event);
    }
 ...
 }

可以看到PhoneWindow類在實現(xiàn)抽象方法superDispatchTouchEvent時沈自,直接將事件交由DecorView處理酌儒。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市枯途,隨后出現(xiàn)的幾起案子忌怎,更是在濱河造成了極大的恐慌籍滴,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,639評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件榴啸,死亡現(xiàn)場離奇詭異孽惰,居然都是意外死亡,警方通過查閱死者的電腦和手機鸥印,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評論 3 385
  • 文/潘曉璐 我一進店門灰瞻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人辅甥,你說我怎么就攤上這事×鞘” “怎么了璃弄?”我有些...
    開封第一講書人閱讀 157,221評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長构回。 經(jīng)常有香客問我夏块,道長,這世上最難降的妖魔是什么纤掸? 我笑而不...
    開封第一講書人閱讀 56,474評論 1 283
  • 正文 為了忘掉前任脐供,我火速辦了婚禮,結(jié)果婚禮上借跪,老公的妹妹穿的比我還像新娘政己。我一直安慰自己,他們只是感情好掏愁,可當(dāng)我...
    茶點故事閱讀 65,570評論 6 386
  • 文/花漫 我一把揭開白布歇由。 她就那樣靜靜地躺著,像睡著了一般果港。 火紅的嫁衣襯著肌膚如雪沦泌。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,816評論 1 290
  • 那天辛掠,我揣著相機與錄音谢谦,去河邊找鬼。 笑死萝衩,一個胖子當(dāng)著我的面吹牛回挽,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播猩谊,決...
    沈念sama閱讀 38,957評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼厅各,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了预柒?” 一聲冷哼從身側(cè)響起队塘,我...
    開封第一講書人閱讀 37,718評論 0 266
  • 序言:老撾萬榮一對情侶失蹤袁梗,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后憔古,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體遮怜,經(jīng)...
    沈念sama閱讀 44,176評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,511評論 2 327
  • 正文 我和宋清朗相戀三年鸿市,在試婚紗的時候發(fā)現(xiàn)自己被綠了锯梁。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,646評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡焰情,死狀恐怖陌凳,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情内舟,我是刑警寧澤合敦,帶...
    沈念sama閱讀 34,322評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站验游,受9級特大地震影響充岛,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜耕蝉,卻給世界環(huán)境...
    茶點故事閱讀 39,934評論 3 313
  • 文/蒙蒙 一崔梗、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧垒在,春花似錦蒜魄、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至推盛,卻和暖如春峦阁,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背耘成。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評論 1 266
  • 我被黑心中介騙來泰國打工榔昔, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人瘪菌。 一個月前我還...
    沈念sama閱讀 46,358評論 2 360
  • 正文 我出身青樓撒会,卻偏偏與公主長得像,于是被迫代替她去往敵國和親师妙。 傳聞我的和親對象是個殘疾皇子诵肛,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,514評論 2 348

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