1. 说明
上节课我们总结了View的Touch事件分发,那么这节课我们就来总结下ViewGroup的Touch事件分发,还是和上节课一样,我们采用示例代码来给大家来分析。
2. 分析
/**
* Email: 2185134304@qq.com
* Created by JackChen 2018/3/25 10:23
* Version 1.0
* Params:
* Description: 自定义ViewGroup
*/
public class TouchViewGroup extends LinearLayout {
public TouchViewGroup(Context context) {
super(context);
}
public TouchViewGroup(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public TouchViewGroup(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
// 事件分发
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
Log.e("TAG" , "ViewGroup dispatchTouchEvent -> " + ev.getAction()) ;
return super.dispatchTouchEvent(ev);
}
// 事件拦截
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
Log.e("TAG" , "ViewGroup onInterceptTouchEvent -> " + ev.getAction()) ;
return super.onInterceptTouchEvent(ev);
}
// 事件触摸
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.e("TAG" , "ViewGroup onTouchEvent -> " + event.getAction()) ;
return super.onTouchEvent(event);
}
}
/**
* Email: 2185134304@qq.com
* Created by JackChen 2018/3/25 10:22
* Version 1.0
* Params:
* Description: 自定义View
*/
public class TouchView extends View {
public TouchView(Context context) {
super(context);
}
public TouchView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public TouchView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.e("TAG" , "View onTouchEvent -> " + event.getAction()) ;
return super.onTouchEvent(event);
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
Log.e("TAG" , "View dispatchTouchEvent -> " + event.getAction()) ;
return super.dispatchTouchEvent(event);
}
}
public class MainActivity extends AppCompatActivity {
private TouchView touch_view;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
touch_view = (TouchView) findViewById(R.id.touch_view);
touch_view.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.e("TAG" , "View onTouch -> " + event.getAction()) ;
return false;
}
});
touch_view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.e("TAG" , "View onClick -> ") ;
}
});
}
}
<?xml version="1.0" encoding="utf-8"?>
<com.jackchen.view_day11_2.TouchViewGroup xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.jackchen.view_day11_2.MainActivity">
<com.jackchen.view_day11_2.TouchView
android:layout_width="200dp"
android:layout_height="200dp"
android:text="Hello World!"
android:id="@+id/touch_view"
android:background="@color/colorAccent"
/>
</com.jackchen.view_day11_2.TouchViewGroup>
首先先自定义一个ViewGroup,实现与View相关的3个方法,dispatchTouchEvent()、onInterceptTouchEvent()、onTouchEvent(),分别是事件分发、事件拦截、事件触摸;
然后写一个自定义View,实现与View相关的2个方法,dispatchTouchEvent()、onTouchEvent(),分别是事件分发、分别触摸,自定义View没有事件拦截方法;
2.1 :正常情况
运行结果是:
03-25 10:55:35.410 16316-16316/com.jackchen.view_day11_2 E/TAG: ViewGroup dispatchTouchEvent -> 0
03-25 10:55:35.410 16316-16316/com.jackchen.view_day11_2 E/TAG: ViewGroup onInterceptTouchEvent -> 0
03-25 10:55:35.410 16316-16316/com.jackchen.view_day11_2 E/TAG: View dispatchTouchEvent -> 0
03-25 10:55:35.410 16316-16316/com.jackchen.view_day11_2 E/TAG: View onTouch -> 0
03-25 10:55:35.410 16316-16316/com.jackchen.view_day11_2 E/TAG: View onTouchEvent -> 0
第一次DOWN(按下):
ViewGroup.dispatchTouchEvent()、ViewGroup.onIterceptTouchEvent()、
View的dispatchTouchEvent、onTouch、onTouchEvent;
第二次MOVE (移动):
ViewGroup的dispatchTouchEvent()、onIterceptTouchEvent()
View的dispatchTouchEvent、onTouch、onTouchEvent;
第三次UP (抬起):
ViewGroup的dispatchTouchEvent、onInterceptTouchEvent、
View的onTouch、onTouchEvent、onClick
2.2 :注释点击事件setOnClickListener,也就是说不要点击事件
运行结果是:
03-25 13:11:10.784 22039-22039/? E/TAG: ViewGroup dispatchTouchEvent -> 0
03-25 13:11:10.784 22039-22039/? E/TAG: ViewGroup onInterceptTouchEvent -> 0
03-25 13:11:10.784 22039-22039/? E/TAG: View dispatchTouchEvent -> 0
03-25 13:11:10.784 22039-22039/? E/TAG: View onTouch -> 0
03-25 13:11:10.784 22039-22039/? E/TAG: View onTouchEvent -> 0
03-25 13:11:10.785 22039-22039/? E/TAG: ViewGroup onTouchEvent -> 0
ViewGroup的dispatchTouchEvent、onInterceptTouchEvent、
View的 dispatchTouchEvent、onTouch、onTouchEvent、
ViewGroup的onTouchEvent
2.3 : 在View的 onTouchEvent()中return true的情况下
第一次DOWN(按下):
ViewGroup的dispatchTouchEvent、onInterceptTouchEvent、
View的dispatchTouchEvent、onTouch、onTouchEvent、
ViewGroup的onTouchEvent
第二次MOVE (移动):
ViewGroup的 dispatchTouchEvent、onInterceptTouchEvent、
View的 dispatchTouchEvent、onTouch、onTouchEvent、
ViewGroup的onTouchEvent
第三次UP (抬起):
ViewGroup的dispatchTouchEvent、onInterceptTouchEvent、
View的 onTouch、onTouchEvent
可以看到,在View的 onTouchEvent返回true时,没有onClick事件,因为 onClick点击事件是在super.onTouchEvent(event)中,返回 true而没有执行super.onTouchEvent(event)方法,所以没有onClick点击事件;
2.4 在ViewGroup的 onInterceptTouchEvent方法返回true情况下
运行结果如下:
03-25 13:40:19.794 23286-23286/? E/TAG: ViewGroup dispatchTouchEvent -> 0
03-25 13:40:19.794 23286-23286/? E/TAG: ViewGroup onInterceptTouchEvent -> 0
03-25 13:40:19.794 23286-23286/? E/TAG: ViewGroup onTouchEvent -> 0
ViewGroup的 dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent