對於android事件分發是android中的一個難點,不少人對它都只知其一;不知其二,緣由呢只是他們並無親自作一個demo,而後認真的去分析一下,只是去網上找一些博客,但博客上對android事件分發的介紹大都篇幅過長,說法也略有差別,因此形成android事件分發成爲一個難點。下面,我用一個簡單的demo來分析一下android事件分發:java
首先自定義了兩個類,一個LinearLayout,一個Button:android
MyLinearLayout以下:ide
public class MyLinearLayout extends LinearLayout{ public MyLinearLayout(Context context) { this(context,null); } public MyLinearLayout(Context context, AttributeSet attrs) { this(context, attrs,0); } public MyLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override public boolean dispatchTouchEvent(MotionEvent ev) { Log.e("touch","MyLinearLayout-----dispatchTouchEvent---begin"); boolean b = super.dispatchTouchEvent(ev); Log.e("touch","MyLinearLayout-----dispatchTouchEvent---" + b ); return b; } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { Log.e("touch","MyLinearLayout-----onInterceptTouchEvent---begin"); boolean b = super.onInterceptTouchEvent(ev); Log.e("touch","MyLinearLayout-----onInterceptTouchEvent---" + b ); return b; } }
MyButton以下:this
public class MyButton extends Button { public MyButton(Context context) { this(context,null); } public MyButton(Context context, AttributeSet attrs) { this(context,attrs,0); } public MyButton(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override public boolean dispatchTouchEvent(MotionEvent event) { Log.e("touch", "MyButton-----dispatchTouchEvent---begin"); boolean b = super.dispatchTouchEvent(event); Log.e("touch", "MyButton-----dispatchTouchEvent---" + b); return b; } }
簡單說一下:在MyLinearLayout中重寫了dispatchTouchEvent和onInterceptTouchEvent,在MyButton中重寫了 dispatchTouchEvent,那在MyButton中爲何沒有onInterceptTouchEvent呢,由於MyButton繼承的是View,View是沒有辦法事件攔截的,記住:只有ViewGroup纔有事件攔截方法。spa
而後在Activity對應的layout中:code
<com.sumu.gefdemo.widget.MyLinearLayout android:id="@+id/layout" android:layout_width="match_parent" android:layout_height="match_parent"> <com.sumu.gefdemo.widget.MyButton android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/button" android:text="點擊" /> </com.sumu.gefdemo.widget.MyLinearLayout>
運行這個demo,而後點擊MyButton,在控制檯有一下的輸出:繼承
03-15 10:19:40.820 3747-3747/com.sumu.gefdemo E/touch: MyLinearLayout-----dispatchTouchEvent---begin 03-15 10:19:40.820 3747-3747/com.sumu.gefdemo E/touch: MyLinearLayout-----onInterceptTouchEvent---begin 03-15 10:19:40.820 3747-3747/com.sumu.gefdemo E/touch: MyLinearLayout-----onInterceptTouchEvent---false 03-15 10:19:40.820 3747-3747/com.sumu.gefdemo E/touch: MyButton-----dispatchTouchEvent---begin 03-15 10:19:40.820 3747-3747/com.sumu.gefdemo E/touch: MyButton-----dispatchTouchEvent---false 03-15 10:19:40.820 3747-3747/com.sumu.gefdemo E/touch: MyLinearLayout-----dispatchTouchEvent---false
解釋一下:事件
1.先是MyLinearLayout中開始執行dispatchTouchEvent方法get
2.而後進入MyLinearLayout的onInterceptTouchEvent方法博客
3.onInterceptTouchEvent返回值爲false,而後又進入了MyButton的dispatchTouchEvent
4.MyButton的dispatchTouchEvent返回值是false
5.MyLinearLayout的dispatchTouchEvent執行完畢,返回值爲false。
你們先不要管這幾個方法的返回值,咱們先關注一下執行的流程:若是你點擊了一個控件,若是這個控件有父控件,先進入父控件的dispatchTouchEvent,而後再進入父控件的onInterceptTouchEvent方法,當onInterceptTouchEvent返回值爲false時,表示事件不攔截,而後又進入到了子控件的dispatchTouchEvent方法進行事件分發,OK,分析完畢。
當咱們把MyLinerLayout的onInterceptTouchEvent返回值直接return true:
@Override public boolean onInterceptTouchEvent(MotionEvent ev) { Log.e("touch","MyLinearLayout-----onInterceptTouchEvent---begin"); boolean b = super.onInterceptTouchEvent(ev); // Log.e("touch","MyLinearLayout-----onInterceptTouchEvent---" + b ); return true; }
再看控制檯:
03-15 11:00:13.530 21053-21053/com.sumu.gefdemo E/touch: MyLinearLayout-----dispatchTouchEvent---begin 03-15 11:00:13.530 21053-21053/com.sumu.gefdemo E/touch: MyLinearLayout-----onInterceptTouchEvent---begin 03-15 11:00:13.530 21053-21053/com.sumu.gefdemo E/touch: MyLinearLayout-----dispatchTouchEvent---false
OK,MyButton的 dispatchTouchEvent沒有執行,表示事件攔截了。
好了,這篇博客的重點就是知道事件分發的流程,下一篇博客再把onTouchEvent加進來。