国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

解析Android點擊事件分發機制

2019-10-22 18:19:27
字體:
來源:轉載
供稿:網友

開頭說說初衷

網上關于點擊事件分發的文章一搜一大堆,標題一看,不是“30分鐘讓你弄明白XXX”就是“這是講解XXX最好的文章”,滿懷憧憬與信心,忍不住興奮的點進去一看,發現不是代碼就全是圖,我基本上看完了所有相關的文章,結果硬是看了三個小時也沒搞懂。所以最后還是決定自己去試一試,看一看點擊事件分發到底是怎么個流程,我寫的肯定不會比其他文章好多少,但是呢,帶著一個初學者的心,去分析這個東西,自己能弄明白的同時,也讓想學習這個的人看了之后有些許收獲,那就足夠了。

運行的環境

所有的源碼都基于API 26,也就是Android8.0奧利奧,Android Studio 3.0.1,想要自己敲代碼試試的同學可以參考一下

進入正題

分析點擊事件分發流程,是想弄明白當我們用手指去點擊屏幕的時候,分為三個動作,按下,移動和抬起,屏幕上的東西是怎么知道我們點了它的,在這中間到底經歷了什么。所以要先來模擬一下這個點擊的過程,看看到底調用了哪些方法。

搭建最簡單的結構

新建Activity,重寫dispatchTouchEvent和onTouchEvent,前面的方法負責點擊事件的分發,后面的方法負責點擊事件的消耗,然后打印三種觸摸事件的觸發

private static final String TAG = MainActivity.class.getSimpleName();@Override  public boolean onTouchEvent(MotionEvent event) {    int action = event.getAction();    switch (action) {      case MotionEvent.ACTION_DOWN:        Log.d(TAG, "Activity onTouchEvent ACTION_DOWN");//按下        break;      case MotionEvent.ACTION_MOVE:        Log.d(TAG, "Activity onTouchEvent ACTION_MOVE");//移動        break;      case MotionEvent.ACTION_UP:        Log.d(TAG, "Activity onTouchEvent ACTION_UP");//抬起        break;    }    return super.onTouchEvent(event);  }@Override  public boolean dispatchTouchEvent(MotionEvent ev) {    int action = ev.getAction();    switch (action) {      case MotionEvent.ACTION_DOWN:        Log.d(TAG, "Activity dispatchTouchEvent ACTION_DOWN");        break;      case MotionEvent.ACTION_MOVE:        Log.d(TAG, "Activity dispatchTouchEvent ACTION_MOVE");        break;      case MotionEvent.ACTION_UP:        Log.d(TAG, "Activity dispatchTouchEvent ACTION_UP");        break;    }    return super.dispatchTouchEvent(ev);  }  

新建一個類繼承自LinearLayout,同樣也重寫dispatchTouchEvent和onTouchEvent,還有因為LinearLayout繼承自ViewGroup,ViewGroup是可以攔截點擊事件的,這個很好理解,因為控件都是放在他里面的嘛。所以還要重寫onInterceptTouchEvent方法

@Override  public boolean onInterceptTouchEvent(MotionEvent ev) {    int action = ev.getAction();    switch (action) {      case MotionEvent.ACTION_DOWN:        Log.d(TAG, "onInterceptTouchEvent ACTION_DOWN");        break;      case MotionEvent.ACTION_MOVE:        Log.d(TAG, "onInterceptTouchEvent ACTION_MOVE");        break;      case MotionEvent.ACTION_UP:        Log.d(TAG, "onInterceptTouchEvent ACTION_UP");        break;      default:        break;    }    return false;  }

(這里有個重點).

這里有個需要注意的地方就是Android的控件有些是默認可以點擊的(如Button),還有一些是默認不可點擊的(如TextView)他們的分發是有一些不同的,這里我們先看不可點擊的,新建一個類繼承android.support.v7.widget.AppCompatTextView,兼容的TextView,同時跟Activity一樣重寫dispatchTouchEvent和onTouchEvent,代碼不貼了,跟上面一樣,它是普通控件,沒有攔截的方法。

開始點擊,移動手指后抬起

然后來點一點屏幕上的控件看看打印的log,dispatchTouchEvent和onTouchEvent都返回默認的實現super,onInterceptTouchEvent默認返回false,表示不攔截,默認的情況打印:

1.--------------------------------------D/MainActivity: Activity dispatchTouchEvent ACTION_DOWND/MyLayout: dispatchTouchEvent ACTION_DOWND/MyLayout: onInterceptTouchEvent ACTION_DOWND/MyTextView: dispatchTouchEvent ACTION_DOWN2.--------------------------------------D/MyTextView: onTouchEvent ACTION_DOWND/MyLayout: onTouchEvent ACTION_DOWND/MainActivity: Activity onTouchEvent ACTION_DOWN3.--------------------------------------D/MainActivity: Activity dispatchTouchEvent ACTION_MOVED/MainActivity: Activity onTouchEvent ACTION_MOVED/MainActivity: Activity dispatchTouchEvent ACTION_MOVED/MainActivity: Activity onTouchEvent ACTION_MOVED/MainActivity: Activity dispatchTouchEvent ACTION_UPD/MainActivity: Activity onTouchEvent ACTION_UP

這是默認的情況,把它分為三個階段:

1. 事件的分發,從上到下,從Activity到Layout到Text的dispatchTouchEvent結束

2. 事件的消耗,從下到上,從Text到Layout到Activity的onTouchEvent結束

3. 這套動作的后續事件交給上個事件的最后消耗者,不經過其他控件的分發

三個函數的其他返回值

dispatchTouchEvent和onTouchEvent都有三種返回情況
- true
- false
- super.dispatchTouchEvent(ev)和super.onTouchEvent(event)

onInterceptTouchEvent有兩種返回,true和false,這樣來看, 組合起來真是情況太多了,寫下來挨個分析看代碼的話怕是要看暈,所以這里用一張圖來看看所有的情況:

普通不可點擊View的事件分發流程

Android點擊事件分發機制,Android,事件分發機制

默認可點擊控件的事件分發

比如Button這種默認可以點擊的控件,或者設置android:clickable=”true”的控件,在分發流程中有一些不同,主要是onTouchEvent的默認方法不同,它直接消耗點擊事件,不再往上傳遞。

可點擊View的事件分發流程

Android點擊事件分發機制,Android,事件分發機制

結語

事件的分發流程到此就結束了,目的已經達到了,找到了我們想要點擊的那個按鈕或者其他控件,總結下來就是從Activity經過ViewGroup然后到View依次分發,然后又從底向上確認自己是否消耗該事件,如果某個對象消耗了,動作的后續事件都由他來處理。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 通许县| 龙门县| 清涧县| 东乌珠穆沁旗| 浮梁县| 汤阴县| 杭锦后旗| 葵青区| 鹤庆县| 麻江县| 隆化县| 厦门市| 三台县| 城固县| 同心县| 晋城| 阳高县| 安平县| 武定县| 麻栗坡县| 潜江市| 东光县| 阜阳市| 扎赉特旗| 合江县| 米林县| 襄城县| 韶关市| 彰化市| 出国| 巴彦淖尔市| 巴塘县| 卢龙县| 赤城县| 武安市| 潍坊市| 九江市| 义马市| 郴州市| 大港区| 葫芦岛市|