Android事件分發詳解(四)——事件傳遞基礎樣本
MainActivity如下:
package com.cn;import android.app.Activity;import android.os.Bundle;import android.view.MotionEvent;import android.view.View;import android.view.View.OnClickListener;import android.view.View.OnTouchListener;/** * Demo描述: * Android事件傳遞基礎 * * 背景知識: * 事件的傳遞方向為:從最外層(Activity)傳遞至最內層(某個View)* 事件的消費方向為:從最內層(某個View)傳遞至最外層(Activity)* * * * Demo構成: * 1 一個普通的Activity中包含一個自訂Button. * 2 覆寫Activity的dispatchTouchEvent和onTouchEvent * 3 自訂Button中覆寫dispatchTouchEvent和onTouchEvent * 兩者的傳回值均為預設值(true). * 4 在Activity中為自訂Button註冊TouchListener, * 覆寫裡面的onTouch(),該方法預設返回false表示事件未消耗. * 5 在Activity中為自訂Button註冊ClickListener, * * * 點擊螢幕上的Button進行測試 * * * Touch事件的處理順序為: * 1 Activity的dispatchTouchEvent()方法 * 如果它返回false表示不分發事件,則2,3,4不會執行 * 2 自訂Button的dispatchTouchEvent()方法 * 如果它返回false表示不分發事件,則3,4不會執行 * 3 Activity中自訂Button的TouchListener執行 * 如果它返回true表示事件已經消耗,則4不會執行 * 4 自訂Button的onTouchEvent()方法 * 如果它返回false(事件未被消費)即返回給自訂Button的dispatchTouchEvent()方法一個false. * 所以自訂Button會中斷事件的分發,即每次只分發ACTION_DOWN事件,不分發ACTION_MOVE和ACTION_UP. * 所以,每次自訂Button只會響應ACTION_DOWN,不會收到ACTION_MOVE和ACTION_UP. * 也正因為這些事件沒有被消耗,所以事件會向上傳遞,於是Activity的onTouchEvent()方法 * 可以響應到一系列的ACTION_DOWN和ACTION_MOVE以及ACTION_UP. * 如果它返回true(事件被消費),那麼事件就不會向上傳遞給Activity了. * Activity自然也收到不到一系列的ACTION_DOWN和ACTION_MOVE以及ACTION_UP. * * 小結: * (1) 每一次的ACTION_DOWN和ACTION_MOVE以及ACTION_UP都會引起每一層的dispatchTouchEvent() * (2) 但是每一層的onTouchEvent()就不一定會執行了.比如下層已經消耗掉了事件,那麼上層就不會響應onTouchEvent()了. * * 5 自訂Button的ClickListener中的onClick()方法 * * * 小結: * 1 因為自訂Button的onTouchEvent預設返回為true. * 表示事件已經消耗,不會繼續向上層傳遞,所以Activity中的onTouchEvent方法不會調用 * 2 再次證明: * View中onTouch()先於onTouchEvent()執行 * View中onTouchEvent()先於onClick()執行,或者說在onTouchEvent()中調用了onClick() * 3 1和2代表的是:事件的傳遞方向-->從最外層(Activity)傳遞至最內層(某個View) * * * * * * 常量對應: * ACTION_DOWN----->0 * ACTION_UP------->1 * ACTION_MOVE----->2 * * 參考資料:www.bkjia.com * Thank you very much * */public class MainActivity extends Activity {private EventButton mEventButton;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);init();} private void init(){ mEventButton=(EventButton) findViewById(R.id.button); mEventButton.setOnTouchListener(new OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {System.out.println(---> 按鈕的OnTouchListener +event.getAction());return false;} }); mEventButton.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View view) {System.out.println(---> 按鈕的OnClickListener 點擊了Button);} }); } @Override public boolean dispatchTouchEvent(MotionEvent ev) { System.out.println(---> Activity dispatchTouchEvent +ev.getAction()+ , it defaulst is true); return super.dispatchTouchEvent(ev); } @Override public boolean onTouchEvent(MotionEvent event) { System.out.println(---> Activity onTouchEvent +event.getAction()+ , it defaulst is false); return super.onTouchEvent(event); } }
EventButton如下:
package com.cn;import android.content.Context;import android.util.AttributeSet;import android.view.MotionEvent;import android.widget.Button;public class EventButton extends Button {public EventButton(Context context, AttributeSet attrs) {super(context, attrs);}@Overridepublic boolean dispatchTouchEvent(MotionEvent event) {System.out.println(---> 按鈕 dispatchTouchEvent , it defaulst is true);return super.dispatchTouchEvent(event);}@Overridepublic boolean onTouchEvent(MotionEvent event) {System.out.println(---> 按鈕 onTouchEvent , it defaulst is true);return super.onTouchEvent(event);//return false;}}
上一篇http://www.bkjia.com/kf/201412/365603.html