日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長(zhǎng)提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

前言

在日常開發(fā)過程中,可能會(huì)遇到這些問題:滑動(dòng)沖突、點(diǎn)擊事件響應(yīng)沖突等問題。那么造成這些問題的根源到底是什么呢?其實(shí)這都是Android事件分發(fā)導(dǎo)致的,只有掌握了事件分發(fā)機(jī)制,才能讓我們從根源上理解并解決這類問題。

事件分發(fā)對(duì)象

事件分發(fā)過程中,涉及到三種UI對(duì)象類型:Activity、ViewGroup、View 及其派生類。三者之間的關(guān)系如下圖:

 

發(fā)生一次點(diǎn)擊事件時(shí),事件會(huì)按照Activity->ViewGroup->View的順序,進(jìn)行事件傳遞。

  • Activity:控制UI頁面的生命周期,是事件分發(fā)的入口。
  • ViewGroup:View的特殊子類,是一組View的集合,是Android中所有布局的父類。
  • View:所有UI組件的基類,常見的Button、TextView等控件都繼承自View。

Android事件分發(fā)機(jī)制,其實(shí)就是Activity、ViewGroup、View三者對(duì)觸摸點(diǎn)擊事件的事件傳遞過程。

事件整體分發(fā)流程

事件分發(fā)流程圖

在整個(gè)事件分發(fā),并響應(yīng)事件的過程中,有三個(gè)重要的方法:

  • dispatchTouchEvent:分發(fā)(傳遞)點(diǎn)擊事件,當(dāng)點(diǎn)擊事件能夠傳遞給當(dāng)前View時(shí),該方法就會(huì)被調(diào)用。
  • onInterceptTouchEvent:判斷是否攔截某個(gè)事件,該方法僅在ViewGroup中存在。一般情況下會(huì)在ViewGroup的dispatchTouchEvent方法中調(diào)用該方法。
  • onTouchEvent:處理點(diǎn)擊事件,在dispatchTouchEvent內(nèi)部調(diào)用。

Activity事件分發(fā)流程

Activity中主要涉及以下兩個(gè)事件方法:

  • boolean dispatchTouchEvent(MotionEvent ev):事件分發(fā)
  • boolean onTouchEvent(MotionEvent event):事件消費(fèi)

在Activity中接受到點(diǎn)擊事件,首先會(huì)執(zhí)行dispatchTouchEvent()方法,進(jìn)行事件分發(fā)。經(jīng)過window、decorView依次傳遞后,頁面上的 ViewGroup會(huì)接收到該事件。ViewGroup如果消費(fèi)了該事件,則分發(fā)結(jié)束(流程在ViewGroup中繼續(xù)向下分發(fā)),未消費(fèi)則繼續(xù)調(diào)用Activity的onTouchEvent 方法處理事件,流程圖如下:

Activity事件分發(fā)流程

ViewGroup事件分發(fā)流程

ViewGroup 涉及到三個(gè)事件分發(fā)與處理的方法:

  • dispatchTouchEvent(MotionEvent ev):事件分發(fā)
  • onIntercepTouchEvent(MotionEvent ev):事件攔截
  • onTouchEvent(MotionEvent ev):事件消費(fèi)

ViewGroup事件分發(fā)流程圖

ViewGroup通過dispatchTouchEvent()方法接收到事件,然后根據(jù)ViewGroup onInterceptTouchEvent()方法的返回值判斷:

  • 返回true,則調(diào)用ViewGroup的onTouchEvent()方法,如果消費(fèi)了事件,則事件傳遞結(jié)束,如果不消費(fèi)事件,則事件傳遞回Activity并執(zhí)行Activity的onTouchEvent()方法;
  • 返回false,則將事件傳遞給子View,由子View繼續(xù)完成事件向下分發(fā)。

View的事件分發(fā)流程

View 主要涉及如下兩個(gè)事件分發(fā)與處理的方法:

  • dispatchTouchEvent(MotionEvent ev):事件分發(fā)
  • onTouchEvent(MotionEvent ev):事件消費(fèi)

 

View事件分發(fā)流程圖

View通過dispatchTouchEvent方法接收到從ViewGroup傳遞過來的事件后,直接調(diào)用 onTouchEvent方法處理事件。如果沒有消費(fèi)事件,則調(diào)用ViewGroup的onTouchEvent方法處理事件,然后繼續(xù)ViewGroup事件流程;如果消費(fèi)了該事件,則分發(fā)結(jié)束。

注意:

在View把事件消費(fèi)后,如果View的onTouch方法返回true,View的dispatchTouchEvent方法會(huì)直接返回true,不會(huì)再調(diào)用View的onClick方法;只有當(dāng)onTouch方法返回false時(shí),才會(huì)有onClick事件處理。

思考點(diǎn)

  • onTouch()和onTouchEvent()的區(qū)別?

這兩個(gè)方法都是在View的dispatchTouchEvent中調(diào)用,但onTouch優(yōu)先于onTouchEvent執(zhí)行。如果在onTouch方法中返回true將事件消費(fèi)掉,onTouchEvent()將不會(huì)再執(zhí)行。

特別注意:請(qǐng)看下面代碼

//1. mOnTouchListener的值不能為空 
//2. 當(dāng)前點(diǎn)擊的控件必須是enable的
mOnTouchListener !=null && (mViewFlags & ENABLED_MASK) == ENABLED &&mOnTouchListener.onTouch(this, event)

因此如果你有一個(gè)控件是非enable的,那么給它注冊(cè)onTouch事件將永遠(yuǎn)得不到執(zhí)行。對(duì)于這一類控件,如果我們想要監(jiān)聽它的touch事件,就必須通過在該控件中重寫onTouchEvent方法來實(shí)現(xiàn)。

  • Touch事件的后續(xù)事件(MOVE、UP)層級(jí)傳遞

接收了ACTION_DOWN事件的函數(shù)不一定能收到后續(xù)事件(ACTION_MOVE、ACTION_UP);如果在某個(gè)對(duì)象(Activity、ViewGroup、View)的dispatchTouchEvent()消費(fèi)事件(返回true),那么收到ACTION_DOWN的函數(shù)也能收到ACTION_MOVE和ACTION_UP。

分享到:
標(biāo)簽:Android
用戶無頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定