一直想写一篇文章记录一下.今天终于写了,比拿超神还要爽
触摸事件的常用方法
onTouch //处理触摸事件
onTouchEvent //处理触摸事件,如果onTouch已经执行并返回true,这个将不执行
dispatchTouchEvent //事件派发
onInterceptTouchEvent//事件拦截
requestDisallowInterceptTouchEvent//是否允许拦截
onTouch
public boolean onTouch(View v, MotionEvent event) {
return true;//返回true.onTouchEvent不执行
}
onTouchEvent
true.派发到下一个界面
false不派发
观察View的onTouchEvent实际处理了OnClick和OnLongClick
dispatchTouchEvent
触摸事件派发
true 派发到子view
false 不派发
onInterceptTouchEvent
事件拦截
true拦截
false 不拦截
requestDisallowInterceptTouchEvent
一般用于在子类是否将事件传递给父类
false 父类进行拦截
true 父类不拦截.子类自己处理
结论测试
调用顺序.
猜想
dispatchTouchEvent -> onInterceptTouchEvent ->onTouch ->onTouchEvent
测试代码
public class TouchTestLayout extends LinearLayout implements View.OnTouchListener{
private static final String TAG = "TouchTestLayout";
public TouchTestLayout(Context context, AttributeSet attrs) {
super(context, attrs);
this.setOnTouchListener(this);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.e(TAG,"onTouchEvent");
return super.onTouchEvent(event);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
Log.e(TAG,"onInterceptTouchEvent");
return super.onInterceptTouchEvent(ev);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
Log.e(TAG,"dispatchTouchEvent");
return super.dispatchTouchEvent(ev);
}
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.e(TAG,"onTouch");
return false;
}
}
测试结果
TouchTestLayout: dispatchTouchEvent
TouchTestLayout: onInterceptTouchEvent
TouchTestLayout: onTouch
TouchTestLayout: onTouchEvent
证明我们的结论是对的
添加子view的调用顺序
现在给TouchTestLayout添加一个子view
<cn.ifreedomer.com.asynctaskdemo.TouchTestLayout
android:id="@+id/testLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<cn.ifreedomer.com.asynctaskdemo.TestChildTextView
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</cn.ifreedomer.com.asynctaskdemo.TouchTestLayout>
TestChildTextView的代码很简单
public class TestChildTextView extends TextView implements View.OnTouchListener {
private static final String TAG = "TestChildTextView";
public TestChildTextView(Context context, AttributeSet attrs) {
super(context, attrs);
setOnTouchListener(this);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.e(TAG,"onTouchEvent");
return super.onTouchEvent(event);
}
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.e(TAG,"onTouch");
return false;
}
}
运行结果
派发的过程明眼人一眼就看出来.就是传给子类,子类再回传回来
父dispatchTouchEvent -> 父onInterceptTouchEvent ->子view的onTouch -> 子类onTouchEvent ->父类onTouch ->父类onTouchEvent
事件拦截
这个比较简单我就简单的测试一下.false不拦截,子类能接受。true拦截,子类收不到.用上面的代码,修改TouchTestLayout的onInterceptTouchEvent
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
Log.e(TAG,"onInterceptTouchEvent");
return true;
}
测试结果
requestDisallowInterceptTouchEvent(disallowIntercept)
作用
源码文档:disallowIntercept True if the child does not want the parent to intercept touch events.(这里就不测试了.官方文档没啥好测的)
(如果子类不想父类拦截触摸事件.disallowIntercept = true)
使用场景
onInterceptTouchEvent会全部拦截.
但是有时我们是有条件的拦截.比如ViewPagerOut里面嵌套了一个ViewPagerInner. ViewPagerOut当里面滑倒尽头可以联动.当ViewPagerInner滑到最左边或者最右边的时候.我们就可以使用
requestDisallowInterceptTouchEvent(false).ViewPagerOut接到事件,开始滑动
重要结尾
最后引用一张最近发现的不错的图
作者:我是asha
链接http://www.jianshu.com/p/fe3d109eb27e
本文详细解析了Android中触摸事件的处理流程,包括dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent及onTouch等方法的调用顺序及其作用,并通过具体测试代码验证了理论分析。
991

被折叠的 条评论
为什么被折叠?



