Android觸摸事件傳遞機制(View事件傳遞機制)

文章共分兩篇金闽,會詳細介紹Activity纯露,View,ViewGroup三者的觸摸事件傳遞機制代芜。一次完整的事件傳遞主要包括三個階段埠褪,分別是事件的分發(fā),攔截和消費。

1.1 觸摸事件的類型

觸摸事件對應的MotionEvent類钞速,事件的類型主要有如下三種

? ? ACTION_DOWN:用戶手指按下的操作,一個按下標志著一個觸摸事件的開始贷掖。

? ? ACTION_MOVE:用戶手指按下在抬起之前,移動的距離超過一定的值渴语,會被判定為? ? ? ? ?????????????????????????????????ACTION_MOVE操作 一般手苹威,指的輕微移動都會觸發(fā)一系列的移動事件。

? ? ACTION_UP:用戶手指離開屏幕的操作驾凶,一次抬起操作標志著一次觸摸事件的結(jié)束牙甫。

1.2 事件傳遞的三個階段

? ? 分發(fā)(Dispatch):事件的分發(fā)對應這dispatchTouchEvent方法,在Android系統(tǒng)中所有的觸摸事件都是通過這個方法分發(fā)的狭郑。

? ? 攔截(Intercept):事件的攔截對應著onInterceptTouchEvent方法腹暖,這個方法只在ViewGroup及其子類中存在。

? ? 消費(Consume):事件的消費對應著onTouchEvent方法翰萨。????

? ? 在Android系統(tǒng)中脏答,擁有事件傳遞能力的類有以下三種:

? ? ? ? Activity:擁有dispatchTouchEvent和onTouchEvent兩個方法。

? ? ? ? ViewGroup:擁有dispatchTouchEvent亩鬼,onInterceptTouchEvent和onTouchEvent兩個方法殖告。

? ? ? ? View:擁有dispatchTouchEvent和onTouchEvent兩個方法。

? ? 1.3 View事件的傳遞機制

? ? ? ?這里所說的View指ViewGroup以外的View雳锋,如TextView黄绩,Button,ImageView等玷过。

? ??public class MyTextView extends AppCompatTextView {

? ? private static final String TAG = MyTextView.class.getSimpleName();

? ? public MyTextView(Context context) {

? ? ? ? super(context);

? ? }

? ? public MyTextView(Context context, @Nullable AttributeSet attrs) {

? ? ? ? super(context, attrs);

? ? }

? ? public MyTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {

? ? ? ? super(context, attrs, defStyleAttr);

? ? }

? ? @Override

? ? public boolean dispatchTouchEvent(MotionEvent event) {

? ? ? ? switch (event.getAction()) {

? ? ? ? ? ? case MotionEvent.ACTION_DOWN:

? ? ? ? ? ? ? ? Log.e(TAG,"dispatchTouchEvent ACTION_DOWN");

? ? ? ? ? ? ? ? break;

? ? ? ? ? ? case MotionEvent.ACTION_MOVE:

? ? ? ? ? ? ? ? Log.e(TAG,"dispatchTouchEvent ACTION_MOVE");

? ? ? ? ? ? ? ? break;

? ? ? ? ? ? case MotionEvent.ACTION_UP:

? ? ? ? ? ? ? ? Log.e(TAG,"dispatchTouchEvent ACTION_UP");

? ? ? ? ? ? ? ? break;

? ? ? ? ? ? ? ? default:

? ? ? ? ? ? ? ? ? ? break;

? ? ? ? }

? ? ? return super.dispatchTouchEvent(event);

? ? }

? ? @Override

? ? public boolean onTouchEvent(MotionEvent event) {

? ? ? ? switch (event.getAction()) {

? ? ? ? ? ? case MotionEvent.ACTION_DOWN:

? ? ? ? ? ? ? ? Log.e(TAG,"onTouchEvent ACTION_DOWN");

? ? ? ? ? ? ? ? break;

? ? ? ? ? ? case MotionEvent.ACTION_MOVE:

? ? ? ? ? ? ? ? Log.e(TAG,"onTouchEvent ACTION_MOVE");

? ? ? ? ? ? ? ? break;

? ? ? ? ? ? case MotionEvent.ACTION_UP:

? ? ? ? ? ? ? ? Log.e(TAG,"onTouchEvent ACTION_UP");

? ? ? ? ? ? ? ? break;

? ? ? ? ? ? default:

? ? ? ? ? ? ? ? break;

? ? ? ? }

? ? ? ? return super.onTouchEvent(event);

? ? }

}

同時定義MainActivity用來展示MyTextView爽丹,在這個Activity中,我們對MyTextView設置了點擊(onClick)觸摸(onTouch)監(jiān)聽辛蚊。

public class MainActivity extends AppCompatActivity implements View.OnTouchListener , View.OnClickListener {

? ? private static final String TAG = MainActivity.class.getSimpleName();

? ? private TextView textView;

? ? @Override

? ? protected void onCreate(Bundle savedInstanceState) {

? ? ? ? super.onCreate(savedInstanceState);

? ? ? ? setContentView(R.layout.activity_main);

? ? ? ? textView = findViewById(R.id.tv);

? ? ? ? textView.setOnTouchListener(this);

? ? ? ? textView.setOnClickListener(this);

? ? }

? ? @Override

? ? public boolean dispatchTouchEvent(MotionEvent event) {

? ? ? ? switch (event.getAction()) {

? ? ? ? ? ? case MotionEvent.ACTION_DOWN:

? ? ? ? ? ? ? ? Log.e(TAG,"dispatchTouchEvent ACTION_DOWN");

? ? ? ? ? ? ? ? break;

? ? ? ? ? ? case MotionEvent.ACTION_MOVE:

? ? ? ? ? ? ? ? Log.e(TAG,"dispatchTouchEvent ACTION_MOVE");

? ? ? ? ? ? ? ? break;

? ? ? ? ? ? case MotionEvent.ACTION_UP:

? ? ? ? ? ? ? ? Log.e(TAG,"dispatchTouchEvent ACTION_UP");

? ? ? ? ? ? ? ? break;

? ? ? ? ? ? default:

? ? ? ? ? ? ? ? break;

? ? ? ? }

? ? ? ? return super.dispatchTouchEvent(event);

? ? }

? ? @Override

? ? public boolean onTouchEvent(MotionEvent event) {

? ? ? ? switch (event.getAction()) {

? ? ? ? ? ? case MotionEvent.ACTION_DOWN:

? ? ? ? ? ? ? ? Log.e(TAG,"onTouchEvent ACTION_DOWN");

? ? ? ? ? ? ? ? break;

? ? ? ? ? ? case MotionEvent.ACTION_MOVE:

? ? ? ? ? ? ? ? Log.e(TAG,"onTouchEvent ACTION_MOVE");

? ? ? ? ? ? ? ? break;

? ? ? ? ? ? case MotionEvent.ACTION_UP:

? ? ? ? ? ? ? ? Log.e(TAG,"onTouchEvent ACTION_UP");

? ? ? ? ? ? ? ? break;

? ? ? ? ? ? default:

? ? ? ? ? ? ? ? break;

? ? ? ? }

? ? ? ? return super.onTouchEvent(event);

? ? }

? ? @Override

? ? public boolean onTouch(View v, MotionEvent event) {

? ? ? ? switch (event.getAction()) {

? ? ? ? ? ? case MotionEvent.ACTION_DOWN:

? ? ? ? ? ? ? ? Log.e(TAG,"MyTextView onTouch ACTION_DOWN");

? ? ? ? ? ? ? ? break;

? ? ? ? ? ? case MotionEvent.ACTION_MOVE:

? ? ? ? ? ? ? ? Log.e(TAG,"MyTextView onTouchEvent ACTION_MOVE");

? ? ? ? ? ? ? ? break;

? ? ? ? ? ? case MotionEvent.ACTION_UP:

? ? ? ? ? ? ? ? Log.e(TAG,"MyTextView onTouchEvent ACTION_UP");

? ? ? ? ? ? ? ? break;

? ? ? ? ? ? default:

? ? ? ? ? ? ? ? break;

? ? ? ? }

? ? ? ? return false;

? ? }

? ? @Override

? ? public void onClick(View v) {

? ? ? ? if (v.getId() == R.id.tv) {

? ? ? ? ? ? Log.e(TAG,"MyTextView onClick");

? ? ? ? }

? ? }

}

運行上面的代碼粤蝎,點擊MyTextView,打印日志袋马。

2019-10-29 16:26:55.547 14052-14052/com.hzy.mydemo E/MainActivity: dispatchTouchEvent ACTION_DOWN

2019-10-29 16:26:55.548 14052-14052/com.hzy.mydemo E/MyTextView: dispatchTouchEvent ACTION_DOWN

2019-10-29 16:26:55.548 14052-14052/com.hzy.mydemo E/MainActivity: MyTextView onTouch ACTION_DOWN

2019-10-29 16:26:55.548 14052-14052/com.hzy.mydemo E/MyTextView: onTouchEvent ACTION_DOWN

2019-10-29 16:26:55.566 14052-14052/com.hzy.mydemo E/MainActivity: dispatchTouchEvent ACTIO

2019-10-29 16:26:55.645 14052-14052/com.hzy.mydemo E/MainActivity: dispatchTouchEvent ACTION_UP

2019-10-29 16:26:55.646 14052-14052/com.hzy.mydemo E/MyTextView: dispatchTouchEvent ACTION_UP

2019-10-29 16:26:55.646 14052-14052/com.hzy.mydemo E/MainActivity: MyTextView onTouchEvent ACTION_UP

2019-10-29 16:26:55.646 14052-14052/com.hzy.mydemo E/MyTextView: onTouchEvent ACTION_UP

2019-10-29 16:26:55.648 14052-14052/com.hzy.mydemo E/MainActivity: MyTextView onClick

不同的返回方式傳遞流程相差甚遠初澎,請看流程圖

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市虑凛,隨后出現(xiàn)的幾起案子碑宴,更是在濱河造成了極大的恐慌,老刑警劉巖桑谍,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件延柠,死亡現(xiàn)場離奇詭異,居然都是意外死亡锣披,警方通過查閱死者的電腦和手機捕仔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進店門匕积,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人榜跌,你說我怎么就攤上這事≈逊啵” “怎么了钓葫?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長票顾。 經(jīng)常有香客問我础浮,道長,這世上最難降的妖魔是什么奠骄? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任豆同,我火速辦了婚禮,結(jié)果婚禮上含鳞,老公的妹妹穿的比我還像新娘影锈。我一直安慰自己,他們只是感情好蝉绷,可當我...
    茶點故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布鸭廷。 她就那樣靜靜地躺著,像睡著了一般熔吗。 火紅的嫁衣襯著肌膚如雪辆床。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天桅狠,我揣著相機與錄音讼载,去河邊找鬼。 笑死中跌,一個胖子當著我的面吹牛咨堤,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播晒他,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼吱型,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了陨仅?” 一聲冷哼從身側(cè)響起津滞,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎灼伤,沒想到半個月后触徐,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡狐赡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年撞鹉,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡鸟雏,死狀恐怖享郊,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情孝鹊,我是刑警寧澤炊琉,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站又活,受9級特大地震影響苔咪,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜柳骄,卻給世界環(huán)境...
    茶點故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一团赏、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧耐薯,春花似錦舔清、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至复斥,卻和暖如春营密,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背目锭。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工评汰, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人痢虹。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓被去,卻偏偏與公主長得像,于是被迫代替她去往敵國和親奖唯。 傳聞我的和親對象是個殘疾皇子惨缆,可洞房花燭夜當晚...
    茶點故事閱讀 44,700評論 2 354