您好,登錄后才能下訂單哦!
Android中的 View框架可以對哪些事件進(jìn)行操作?很多新手對此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。
一.Android View框架提供了3個(gè)對事件的主要操作概念。
1、事件的分發(fā)機(jī)制,dispatchTouchEvent。主要是parent根據(jù)觸摸事件的產(chǎn)生位置,以及child是否愿意負(fù)責(zé)處理該系列事件等狀態(tài),向其child分發(fā)事件的機(jī)制。
2、事件的攔截機(jī)制,onInterceptTouchEvent。主要是parent根據(jù)它內(nèi)部的狀態(tài)、或者child的狀態(tài),來把事件攔截下來,阻止其進(jìn)一步傳遞到child的機(jī)制。
3、事件的處理機(jī)制,onTouchEvent。主要是事件序列的接受者(可以是一個(gè)View或者ViewGroup),對事件作出處理,并且向其parent傳遞處理結(jié)果的機(jī)制。
二.在Java中,傳遞計(jì)算結(jié)果,有很多種途徑,這里采用的是一種適用于同步調(diào)用的方法,返回值的方法。每個(gè)機(jī)制都使用boolean類型作為其返回值,那么每個(gè)機(jī)制的每個(gè)返回值是什么含義呢。
1、事件的分發(fā)機(jī)制,dispatchTouchEvent。
true-事件被以該節(jié)點(diǎn)為根節(jié)點(diǎn)的View樹成功處理,此時(shí)該事件就算是處理完成了,事件不會再向上返還給View的父節(jié)點(diǎn)(把事件分發(fā)過來的那個(gè)節(jié)點(diǎn))。
false-以該節(jié)點(diǎn)為根節(jié)點(diǎn)的View樹種,沒有一個(gè)View(包括該View)成功處理了此事件,所以事件會向上返還給View的父節(jié)點(diǎn)(把事件分發(fā)過來的那個(gè)節(jié)點(diǎn))。
2、事件的攔截機(jī)制,onInterceptTouchEvent。主要是parent根據(jù)它內(nèi)部的狀態(tài)、或者child的狀態(tài),來把事件攔截下來,阻止其進(jìn)一步傳遞到child的機(jī)制。
true-當(dāng)前ViewGroup(因?yàn)閂iew中沒有該方法,而沒有child的VIew也不需要有攔截機(jī)制)希望該事件不再傳遞給其child,而是希望自己處理。
false-當(dāng)前ViewGroup不準(zhǔn)備攔截該事件,事件正常向下分發(fā)給其child。
3、事件的處理機(jī)制,onTouchEvent。主要是事件序列的接受者(可以是一個(gè)View或者ViewGroup),對事件作出處理,并且向其parent傳遞處理結(jié)果的機(jī)制。
true-表示該View成功處理了該事件,該處理結(jié)果會向上通知給其parent。
false-表示該View沒有成功處理該事件,那么它的parent會有機(jī)會來處理該事件(parent標(biāo)記為事件序列接受者,parent 的 onTouchEvent 在 Down 事件時(shí)返回true)。
三.源代碼分析
View:
1、dispatchTouchEvent:
/** 把事件分發(fā)到目標(biāo)對象,因?yàn)檫@里是View對象,默認(rèn)不含有child,所以這里他會把事件分發(fā)給自己 */
public boolean dispatchTouchEvent(MotionEvent event);
public boolean dispatchTouchEvent(MotionEvent event){ boolean result = false; //如果有事件監(jiān)聽器,先讓監(jiān)聽器處理事件。 if (mOnTouchListener.onTouch(event)) { //如果監(jiān)聽器成功處理了該事件,處理結(jié)果設(shè)置為true。 result = true; } //如果沒有監(jiān)聽器,就調(diào)用自身的onTouchEvent方法來處理事件。 if (!resutlt && onTouchEvent(event)) { //如果自身的onTouchEvent成功處理事件,處理結(jié)果設(shè)置為true。 result = true; } return result; }
ViewGroup:
1、onInterceptTouchEvent
/** 默認(rèn)實(shí)現(xiàn)是返回false,也就是默認(rèn)不攔截任何事件 */
public boolean onInterceptTouchEvent(MotionEvent ev);
2、dispatchTouchEvent
/** 根據(jù)內(nèi)部攔截狀態(tài),向其child或者自己分發(fā)事件 */
public boolean dispatchTouchEvent(MotionEvent ev);
public boolean dispatchTouchEvent(MotionEvent ev) { if (ACTION_DOWN事件 || 沒有事件處理對象) { if (允許攔截事件,該標(biāo)志位由child調(diào)用requestDisallowInterceptTouchEvent<span >設(shè)置</span>) { //查詢攔截機(jī)制的結(jié)果,根據(jù)該結(jié)果來判斷是否需要攔截 intercepted = onInterceptTouchEvent(ev); } else { //不允許攔截,那么不攔截 intercepted = false; } } else { //不是DOWN,并且有處理對象,允許攔截,中斷事件傳遞 intercepted = true; } if (不取消 && 不攔截) { if (ACTION_DOWN) { //找尋接收事件序列的對象,其他事件不需要再計(jì)算事件產(chǎn)生對象,試想一下滑動(dòng)一個(gè)ListView,當(dāng)手指滑動(dòng)出ListView的范圍時(shí),依然還是ListView響應(yīng)后續(xù)事件。 for (遍歷所有childView) { if (觸摸點(diǎn)不在childView內(nèi)部) { continue; } if (childView.dispatchTouchEvent(event)) { 保存處理該事件的View,后續(xù)事件直接傳遞到該View,不要重新計(jì)算; } } } if (還沒有事件處理對象) { //當(dāng)前View樹中沒找到合適的child處理對象,把事件給自己處理,View.dispatchTouchEvent()就是把事件分發(fā)給自己 super.dispatchTouchEvent(event); } else { //傳遞給child childView.dispatchTouchEvent(event); } } else if (攔截) { //攔截事件,把事件給自己處理,View.dispatchTouchEvent()就是把事件分發(fā)給自己 super.dispatchTouchEvent(event); } return 處理結(jié)果; }
3、requestDisallowInterceptTouchEvent
/** 干澀parent的事件分發(fā)機(jī)制,通知parent,是否攔截后續(xù)事件,如果設(shè)置為true,parent就不會攔截該事件,不管什么狀態(tài)。設(shè)置為false,parent走正常的攔截流程 */
public void requestDisallowInterceptTouchEvent(boolean disallowIntercept);
public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) { if (已經(jīng)是當(dāng)前要設(shè)置的狀態(tài)) { // 已經(jīng)處于這個(gè)狀態(tài), 假設(shè)我們的parent也是這個(gè)狀態(tài) return; } 設(shè)置該狀態(tài); // 傳遞給parent if (有父容器) { 設(shè)置父容器的攔截狀態(tài); } }
看完上述內(nèi)容是否對您有幫助呢?如果還想對相關(guān)知識有進(jìn)一步的了解或閱讀更多相關(guān)文章,請關(guān)注億速云行業(yè)資訊頻道,感謝您對億速云的支持。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。