本篇仅作为自学笔记,以及学习分享,内容来源于:
https://blog.youkuaiyun.com/qq_30379689/article/details/53967177#commentBox
关于Android事件分发机制,面试回答总结就是以下几点:
- dispatchTouchEvent
- return true:表示该View内部消化掉了所有事件
- return false:表示事件在本层不再继续进行分发,并交由上层控件的onTouchEvent方法进行消费
- return super.dispatchTouchEvent(ev):默认事件将分发给本层的事件拦截onInterceptTouchEvent方法进行处理
- onInterceptTouchEvent
- return true:表示将事件进行拦截,并将拦截到的事件交由本层控件的onTouchEvent进行处理
- return false:表示不对事件进行拦截,事件得以成功分发到子View
- return super.onInterceptTouchEvent(ev):默认表示不拦截该事件,并将事件传递给下一层View的dispatchTouchEvent
- onTouchEvent
- return true:表示onTouchEvent处理完事件后消费了此次事件
- return fasle:表示不响应事件,那么该事件将会不断向上层View的onTouchEvent方法传递,直到某个View的onTouchEvent方法返回true
- return super.dispatchTouchEvent(ev):表示不响应事件,结果与return false一样
自定义MyView
/**
* Created by zzf on 2018/8/29.
*/
public class MyView extends View {
public MyView(Context context) {
super(context);
}
public MyView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
LogUtils.d("MyView------->onTouchEvent");
return super.onTouchEvent(event);
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
LogUtils.d("MyView------->dispatchTouchEvent");
return super.dispatchTouchEvent(event);
}
}
自定义MyViewGroup01
/**
* Created by zzf on 2018/8/29.
*/
public class MyViewGroup01 extends LinearLayout {
public MyViewGroup01(Context context) {
super(context);
}
public MyViewGroup01(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public MyViewGroup01(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
LogUtils.d("MyViewGroup01------->dispatchTouchEvent");
return super.dispatchTouchEvent(ev);
// return false;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
LogUtils.d("MyViewGroup01------->onInterceptTouchEvent");
return super.onInterceptTouchEvent(ev);
// return false;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
LogUtils.d("MyViewGroup01------->onTouchEvent");
// return super.onTouchEvent(event);
return false;
}
}
自定义MyViewGroup02
/**
* Created by zzf on 2018/8/29.
*/
public class MyViewGroup02 extends LinearLayout {
public MyViewGroup02(Context context) {
super(context);
}
public MyViewGroup02(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public MyViewGroup02(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
LogUtils.d("MyViewGroup02------->dispatchTouchEvent");
return super.dispatchTouchEvent(ev);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
LogUtils.d("MyViewGroup02------->onInterceptTouchEvent");
return super.onInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
LogUtils.d("MyViewGroup02------->onTouchEvent");
return super.onTouchEvent(event);
}
}
xml布局文件
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.haiyungroup.oceansonic.customview.MyViewGroup02
android:background="#ff0000"
android:layout_width="300dp"
android:layout_height="500dp">
<com.haiyungroup.oceansonic.customview.MyViewGroup01
android:background="#00ff00"
android:layout_width="200dp"
android:layout_height="400dp">
<com.haiyungroup.oceansonic.customview.MyView
android:background="#0000ff"
android:layout_width="@dimen/dimen_150dp"
android:layout_height="300dp" />
</com.haiyungroup.oceansonic.customview.MyViewGroup01>
</com.haiyungroup.oceansonic.customview.MyViewGroup02>
</FrameLayout>
分析事件传递
点击MyView(即蓝色部分):先接收事件的是父容器(MyViewGroup02)往下分发,而事件的分发过程中分为两步骤
- 分发过程
- 处理过程
其正常的分发事件结果为
//分发过程
MyViewGroup02 dispatchTouchEvent
MyViewGroup02 onInterceptTouchEvent
MyViewGroup01 dispatchTouchEvent
MyViewGroup01 onInterceptTouchEvent
MyView dispatchTouchEvent
//处理过程
MyView onTouchEvent
MyViewGroup01 onTouchEvent
MyViewGroup02 onTouchEvent
1、dispatchTouchEvent(分发事件)
如果在MyViewGroup01的dispatchTouchEvent方法中返回true,表示需要在MyViewGroup01消费了整个事件,即不会再分发,也不会再处理。dispatchTouchEvent方法中返回true的打印信息
//分发过程
MyViewGroup02 dispatchTouchEvent
MyViewGroup02 onInterceptTouchEvent
MyViewGroup01 dispatchTouchEvent
如果在MyViewGroup01的dispatchTouchEvent方法中返回false,表示在MyViewGroup01点击事件在本层不再继续进行分发,并交由上层控件的onTouchEvent方法进行消费。dispatchTouchEvent方法中返回false的打印信息
//分发过程
MyViewGroup02 dispatchTouchEvent
MyViewGroup02 onInterceptTouchEvent
MyViewGroup01 dispatchTouchEvent
//处理过程
MyViewGroup02 onTouchEvent
2、onInterceptTouchEvent(拦截事件)
如果在MyViewGroup01的onInterceptTouchEvent方法中返回true,表示需要在MyViewGroup01拦截这个点击事件,不再继续往下分发,即MyView不再执行dispatchTouchEvent方法。但是只是分发结束了而已,接着开始处理事件。下面是onInterceptTouchEvent方法中返回true的打印信息
//分发过程
MyViewGroup02 dispatchTouchEvent
MyViewGroup02 onInterceptTouchEvent
MyViewGroup01 dispatchTouchEvent
MyViewGroup01 onInterceptTouchEvent
//处理过程
MyViewGroup01 onTouchEvent
MyViewGroup02 onTouchEvent
如果在MyViewGroup01的onInterceptTouchEvent方法中返回false,表示需要在MyViewGroup01不会拦截这个点击事件,继续往下分发。下面是onInterceptTouchEvent方法中返回false的打印信息
//分发过程
MyViewGroup02 dispatchTouchEvent
MyViewGroup02 onInterceptTouchEvent
MyViewGroup01 dispatchTouchEvent
MyViewGroup01 onInterceptTouchEvent
MyView dispatchTouchEvent
//处理过程
MyView onTouchEvent
MyViewGroup01 onTouchEvent
MyViewGroup02 onTouchEvent
3、onTouchEvent(消费事件)
如果MyViewGroup01的onTouchEvent方法中返回true,表示MyViewGroup01可以将该事件直接消费掉了,即分发结束后,处理事件的时候,直接处理到MyViewGroup01就可以结束了。下面是onTouchEvent方法中返回true的打印信息
//分发过程
MyViewGroup02 dispatchTouchEvent
MyViewGroup02 onInterceptTouchEvent
MyViewGroup01 dispatchTouchEvent
MyViewGroup01 onInterceptTouchEvent
MyView dispatchTouchEvent
//处理过程
MyView onTouchEvent
MyViewGroup01 onTouchEvent
如果MyViewGroup01的onTouchEvent方法中返回false,表示MyViewGroup01不可以将该事件直接消费掉,即事件继续往上处理。下面是onTouchEvent方法中返回false的打印信息
//分发过程
MyViewGroup02 dispatchTouchEvent
MyViewGroup02 onInterceptTouchEvent
MyViewGroup01 dispatchTouchEvent
MyViewGroup01 onInterceptTouchEvent
MyView dispatchTouchEvent
//处理过程
MyView onTouchEvent
MyViewGroup01 onTouchEvent
MyViewGroup02 onTouchEvent