本文能给你带来和解决一些你模糊的Touch事件概念及用法
- 1.掌握View及ViewGroup的TouchEvent事件分发机制
- 2.为解决View滑动冲突及点击事件消费提供支持
- 3.为你解决面试中的一些问题。
Touch事件分发中只有两个主角:ViewGroup和View。
Activity的Touch事件事实上是调用它内部的ViewGroup的Touch事件,可以直接当成ViewGroup处理。
Activity、ViewGroup、View都关心Touch事件,其中ViewGroup的关心的事件有三个:onInterceptTouchEvent、dispatchTouchEvent、onTouchEvent。
Activity和View关心的事件只有两个:dispatchTouchEvent、onTouchEvent。
只有ViewGroup可以对事件进行拦截。
在Android中Touch**触摸事件**主要包括点击(onClick)、长按(onLongClick)、拖拽(onDrag)、滑动(onScroll)等,
其中Touch的第一个状态是 ACTION_DOWN,表示按下了屏幕后,touch将会有后续事件,比如移动、抬起等。
一个Action_DOWN,一个ACTION_UP,许多个ACTION_MOVE,构成了Android中众多的Touch交互事件。
安卓里经常会有多个布局嵌套,View重叠,View的Visibility设置等等,还有ViewGroup包含View的情况。
这个时候点击到子View时,其实也是同时点到ViewGroup这个父控件的,那是把这个点击事件应该是怎么分发的呢(有没有遇到过listview或recyclerview的item事件或者是item中的控件是不是没反应撒)?
触摸事件分发机制涉及的三个重要方法:
public boolean dispatchTouchEvent(MotionEvent event)
dispatchTouchEvent用来进行事件的分发。如果事件能够传递给当前的View,那么此方法一定会被调用,
返回结果受当前View或者是ViewGroup的onTouchEvent和下级View的dispatchTouchEvent方法的影响,表示是否消耗当前事件。
public boolean onInterceptTouchEvent(MotionEvent event)
onInterceptTouchEvent是ViewGroup提供的方法,用来判断是否拦截某个事件,如果当前View拦截了某个事件,
那么在同一个事件序列当中,此方法不会被再次调用,返回结果表示是否拦截当前事件。默认返回false,返回true表示拦截。
public boolean onTouchEvent(MotionEvent event)
onTouchEvent在dispatchTouchEvent方法中调用,用来处理点击事件,返回结果表示是否消耗当前的事件,如果不消耗,
则在同一个事件序列中,当前View无法再次接受到事件。view中默认返回true,表示消费了这个事件。
今天所使用的Demo目录结构及Activity如图所示:
首先我们来看一下dispatchTouchEvent(MotionEvent event)
布局activity_touch_test.xml
<?xml version="1.0" encoding="utf-8"?>
<com.shanlovana.rcimageview.touchviews.GrandPaViewGroup
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_touch_test"
android:layout_width=