androidtouch,android透傳消息

Android中touch和click事件的區(qū)別

touch是觸摸,

成都服務(wù)器托管,創(chuàng)新互聯(lián)建站提供包括服務(wù)器租用、光華機(jī)房服務(wù)器托管、帶寬租用、云主機(jī)、機(jī)柜租用、主機(jī)租用托管、CDN網(wǎng)站加速、空間域名等業(yè)務(wù)的一體化完整服務(wù)。電話咨詢:18982081108

分為ACTION_DOWN(剛接觸屏幕那一下)

ACTION_MOVE(在屏幕上移動)

ACTION_UP(抬起來)

以上3個都可以有不止一個觸摸點來觸發(fā)

click是一個手指DOWN,過一段時間再UP,并且此時間間隔不足以觸發(fā)長按,

同時MOVE小于一定范圍,的一個組合。

Android中的Touch事件處理如何去掉這種警告

用注解, 打個@SuppressLint("ClickableViewAccessibility")

這個警告是說,有可能會和點擊事件發(fā)生沖突

如果你在touch中返回了true,那么就不會響應(yīng)onClick事件了

你必須調(diào)用一下view.performClick(),才會觸發(fā)

view.setOnTouchListener(new View.OnTouchListener() {

@SuppressLint("ClickableViewAccessibility")

@Override

public boolean onTouch(View v, MotionEvent event) {

// TODO Auto-generated method stub

return false;

}

});

android中怎么控件的touch事件

Touch事件的傳遞

首先我們要了解在android系統(tǒng)里面有幾個地方會走touch事件,這個是老生常談的問題了,但是我還是希望寫一下這個問題,因為溫故而知新嘛,我們首先得知道VIew類這種不能作為容器的類只會有這兩個函數(shù):

[java] view plain copy print?

@Override

public boolean dispatchTouchEvent(MotionEvent event) {

// TODO Auto-generated method stub

return super.dispatchTouchEvent(event);

}

@Override

public boolean onTouchEvent(MotionEvent event) {

// TODO Auto-generated method stub

return super.onTouchEvent(event);

Android 多點觸控算法理解(Multi-touch)

三個手指向屏幕傳遞的東西可以被抽象為一個個的觸摸點(Pointer)。

按照觸碰到屏幕的順序來分,每個Pointer都有一個index,這個算法有點特別?,F(xiàn)在舉例來幫助你理解。

看到Index,你是否想起了數(shù)組下標(biāo)?沒錯你可以認(rèn)為這三個Pointer被安置在了一個數(shù)組里,數(shù)組大小為Pointer的個數(shù)。

有一天,我拿右手的三根手指(食指A,中指B,無名指C)在屏幕上做滑動手勢,我是 先用食指A 接觸屏幕, 再拿中指B 接觸到, 最后拿無名指C 接觸到屏幕,這三根手指的起始位置都貼著屏幕的 最左邊 也就是 X軸接近于0 的地方。這時候 以觸碰到屏幕的次序為依據(jù) ,這三根手指分別被賦予了各自的index,其中 食指A最先 接觸,index為 0 ; 中指B第二個 接觸,index為 1 ; 無名指C第三個 接觸,index為 2 ;

無聊透頂?shù)奈以谕一瑒拥倪^程中,把 中指B松開 了,這下 index為1的中指B 從數(shù)列中被移除了,安卓說:哦, index為1 的這個地方被移除過Pointer,并且這個index為1的位置還是 第一個被移除 的,我記錄下來了。

移除完后呢,總不能空著吧,現(xiàn)在就 兩個 Pointer在屏幕上,我總不能按三個來算吧。我是把目前 index為0 的 Pointer(食指A) 轉(zhuǎn)移到index為1的位置上,還是把目前 index為2 的 Pointer( 無名指C ) 轉(zhuǎn)移到index為1的位置上呢?

是的,谷歌和你一樣都很機(jī)智,他們把 index為2的向前移 了,這樣數(shù)組尺寸就變小了。

既然之前說了我無聊透頂,目前我好像還不夠無聊,為了貫徹這個詞語,我在快要滑到 屏幕右側(cè) 的時候,我 又加了 一根手指進(jìn)來,這次加的還不是原來那根 黃金中指B ,而是我的 小拇指D !而且非常風(fēng)騷地伸到了屏幕的 左側(cè) 去了,這意味著我這個 Pointer小拇指D的X值是很小 的,正當(dāng)我盯著 index為2的位置 觀看我風(fēng)騷小拇指創(chuàng)造的位置數(shù)據(jù)時,驚奇地發(fā)現(xiàn)我的小拇指被賦予的 index竟然為1?。?! 在后來的實驗中, 不管我放的 是原來率先釋放的中指B還是什么一陽指,衛(wèi)生指。他們被賦予的 index都是1?。?!

比如index分別為0,1,2,3的四個Pointer,其中 index為2的Pointer率先 中途移除,然后 index為3的Pointer接著被移除 ,系統(tǒng)將 記錄 哪個index是 最先出現(xiàn)空缺 的,哪個index是 第二個出現(xiàn)空缺 的,然后接下來新產(chǎn)生的Pointer將按 產(chǎn)生的順序 ,先來的放到最先出現(xiàn)空缺的index上,在這里,最新來的Pointer將被放置在 最先出現(xiàn)空缺的 index為 2 的位置上。 下一個來的 Pointer將被放置在 index為3 的位置上.

Android Touch事件分發(fā)處理機(jī)制詳解

Android應(yīng)用的開發(fā)過程不可能不涉及到Touch事件的處理,簡單地如設(shè)置OnClickListener、OnLongClickListener等監(jiān)聽器處理View的點擊事件,復(fù)雜地如在自定義View中通過重寫onTouchEvent來捕獲用戶交互事件以定制出各種效果,在使用的過程中或多或少會遇到一些奇怪的Bug,讓你對Touch事件“從哪來,到哪去”產(chǎn)生迷之疑惑,經(jīng)過多少次徘徊之后終于決定系統(tǒng)的分析下源碼,本文就給大家分享下我的收獲。

MotionEvent作為Touch事件的載體,采用時間片來管理Touch事件所有相關(guān)行為的數(shù)據(jù),本文這樣理解時間片這個概念:

通常MotionEvent會將觸發(fā)當(dāng)前事件的Pointer作為主要Pointer,其PointerIndex為0,而MotionEvent通過提供getX()這類不帶index參數(shù)的接口以更方便的操作主要Pointer的數(shù)據(jù)。

了解了MotionEvent的組成結(jié)構(gòu)之后,接下來就可以分析MotionEvent包含的事件類型了,MotionEvent通過getAction接口來獲取事件Action,而Action中低8位地址存儲的是事件類型(對于觸摸事件來說,主要包括Down、Move、Up、Cancel、PointerDown、PointerUp),高8位地址存儲的是PointerId(當(dāng)事件類型為PointerDown、PointerUp時)。通常來說事件會以Down開始,以Up或Cancel結(jié)束,各事件所承擔(dān)的角色以及各自的特點在分析事件分發(fā)與處理的過程時再詳細(xì)說明。

另外,MotionEvent中的Flag需要說明一下:

本文僅分析Touch事件在Framework中Java層的傳遞,因此從事件傳遞到Activity開始分析。當(dāng)Touch事件傳遞給Activity時,會調(diào)用Activity.dispatchTouchEvent(MotionEvent),Activity會將事件傳遞給其Window進(jìn)行處理,實際會調(diào)用PhoneWindow.superDispatchTouchEvent(MotionEvent),PhoneWindow會將該事件傳遞給Android中View層級中的頂層View(即DecorView)進(jìn)行處理:

在Window未設(shè)置Callback的情況下,會調(diào)用父類的dispatchTouchEvent,DecorView繼承自FrameLayout,然后FrameLayout并未實現(xiàn)dispatchEvent,因此最終調(diào)用ViewGroup.dispatchTouchEvent,也就是Touch事件分發(fā)的核心邏輯所在,前文中提到MotionEvent中事件類型主要包括Down、Move、Up、Cancel、PointerDown、PointerUp,而dispatchTouchEvent根據(jù)事件的不同類型會做不同處理,因此這里分別進(jìn)行分析:

Down事件處理

非異常情況下,Touch事件的事件周期總是以Down事件開始的,因此Down事件在整個事件分發(fā)邏輯中起關(guān)鍵作用,將決定了后續(xù)Move、Up及Cancel事件的處理主體,先看一張Down事件分發(fā)的流程圖:

從流程圖中可以看到,Down事件的分發(fā)邏輯主要目的在于尋找到能處理該Touch事件的View控件(該View為以當(dāng)前ViewGroup為Root節(jié)點的View層級中的View,利用尋找到的View創(chuàng)建事件處理Target),整個處理邏輯主要包含以下幾步:

Move、Up、Cancel事件處理

完成Down事件的分發(fā)邏輯后,就確定了該Down事件后續(xù)Move、Up及Cancel事件的處理主體(注意:這里并沒有確定PointerDown事件的處理主體,關(guān)于PointerDown事件的分發(fā)邏輯稍后分析),先通過一張流程圖來感受下Move、Up、Cancel事件的分發(fā)邏輯:

從流程圖可以看出,對于Move、Up、Cancel事件的分發(fā)步驟如下:

PointerDown事件處理

PointerDown事件是在支持多Pointer(調(diào)用setMotionEventSplittingEnabled將FLAG_SPLIT_MOTION_EVENTS置位)的環(huán)境下,當(dāng)有新的Pointer按下時產(chǎn)生的,該事件處理的特殊性在于會重新遍歷View層級,尋找可以處理新Pointer事件的Target,具體流程參考Down事件的分發(fā)邏輯;遍歷結(jié)束若仍沒有找到處理該事件的Target,則會將新Pointer的處理權(quán)設(shè)置給已有Target中最早被添加的Target。完成Target的尋找之后,會將該事件通過dispatchTransformedTouchEvent傳遞至所有已有Target進(jìn)行處理,可以通過下面流程圖,對PointerDown事件的處理有一個更全局的認(rèn)識:

PointerUp事件處理

相對于Up事件來說,對于PointerUp事件的處理區(qū)別在于當(dāng)傳遞至所有已有Target結(jié)束之后并不能標(biāo)記以Down事件起始的整個事件周期結(jié)束,僅能標(biāo)記其關(guān)聯(lián)Pointer(以PointerDown事件起始)的事件周期結(jié)束,因此不會清除所有狀態(tài),而僅會從已有Target中移除掉與該Pointer相關(guān)的部分。

onInterceptTouchEvent

在ViewGroup進(jìn)行事件分發(fā)的過程中,會調(diào)用該函數(shù)來確定是否需要攔截事件,當(dāng)該函數(shù)返回true時該事件將會被攔截,即不會進(jìn)行正常的View層級傳遞,而是直接由該ViewGroup來處理,而攔截后的操作需要根據(jù)攔截事件的類型不同而不同:

dispatchTransformedTouchEvent(MotionEvent event, boolean cancel, View child, int desiredPointerIdBits)

在將事件傳遞給Target進(jìn)行處理之前會調(diào)用該函數(shù)對MotionEvent進(jìn)行處理:

MotionEvent.split(int idBits)

判斷一個View控件是否消費一個事件,是由View.dispatchEvent的返回值來決定的,而View.dispatchEvent用于尋找事件的最終消費者,話不多說,還是通過一張流程圖來個直觀感受:

從流程圖中可以看出,View會根據(jù)ouch事件對Scroll狀態(tài)進(jìn)行調(diào)整,并尋找該事件的最終處理器:

View.dispatchEvent將向其直接ViewGroup返回是否消費掉該事件,返回值將決定上級ViewGroup是否需要繼續(xù)詢問其他子View是否需要消費該事件。這就是View中分發(fā)事件的邏輯,真是簡單粗暴!

從View.dispatchEvent的分析中可以發(fā)現(xiàn)當(dāng)未對View設(shè)置mTouchListener或mTouchListener未消費掉該事件時,Touch事件最終將由View.onTouchEvent來決定是否消費,自定義View可以重寫該方法實現(xiàn)自身的邏輯,此處僅分析View中的通用處理邏輯:

從上述分析可以很開心地發(fā)現(xiàn)熟悉的onClick及onLongClick事件的產(chǎn)生邏輯,若是之前沒看過類似的文章,應(yīng)該會有原來如此的感覺吧,哈哈~~

至此,Touch事件的分發(fā)與處理流程算是走通了,個人看完整個源碼之后有種豁然開朗的感覺,能很清晰的分析向“為什么事件有時候傳到某個View有時候卻不傳?”、“有時候只傳前面幾個事件后面卻不傳了?”等問題,也希望本文的分析能讓你更清晰地感知Android中Touch事件的傳遞流程,如果發(fā)現(xiàn)文中有何錯誤,希望不吝賜教!

分享名稱:androidtouch,android透傳消息
標(biāo)題路徑:http://muchs.cn/article4/phgdie.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供商城網(wǎng)站定制開發(fā)、標(biāo)簽優(yōu)化網(wǎng)頁設(shè)計公司、App開發(fā)、外貿(mào)建站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

h5響應(yīng)式網(wǎng)站建設(shè)