Android滑动冲突与事件分发机制浅析

 案例开头是要先装会比的,但是今天例外,because ..... 

 说到滑动冲突,真tm是个让人蛋疼的问题,下面  我来给大家 浅浅的谈谈我的理解。

 scrollview 是个好东西吧,对的,没错,他可以让我们的布局滑动起来,提现它的优美,这时,突然在它里面 出现了一个viewpager , 然后我们run  一下程序,恩,发现一切还是那么优美,然后我们轻轻用手滑动一下屏幕,what the fox say?   为毛我下拉  viewpager  整个屏幕没反应,什么鬼,一定有bug,哈哈哈,我发现了谷歌的一个bug,好了,别装逼了,产品经理催着你搞呢...
 

遇到这么一个B问题,莫慌,我来带领你实现翻盘计划,  首先在 解决整个问题之前,你首先并且必须要 深入理解一下  android touch 事件 的分发机制,


看到上面这张图了吧,没错,是我从网上抄的,咳咳,,


Touch事件分发中只有两个主角:ViewGroup和View。

ViewGroup 可以简单的理解有  3个 touch事件相关的方法:

1.onInterceptTouchEvent

2.dispatchTouchEvent

3.onTouchEvent

View 可以简单的理解有  2个 touch事件相关的方法:

1.dispatchTouchEvent

2.onTouchEvent


ok,重点来了,

1.    onInterceptTouchEvent这个方法 是拦截touch 事件方法,你可以想,作为viewgroup,我需要向我下面的子view 下达touch事件命令,当然我有权 对下达的命令做更改, 

 
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
   return super.onInterceptTouchEvent(ev);
}


作为一个boolean 返回类型的方法,当返回false 时,表示touch事件可以继续向子view传递,当返回true时,表示 touch事件被拦截,已经消耗,并不在往下传递, 举个例子:Linearlayout 下有个 button控件, 如果我重写 
Linearlayout 的 onInterceptTouchEvent ,并且直接return true,  你再去调用 
button的点击事件,会发现点击事件失效,当然 onInterceptTouchEvent  作用仅仅如此,决定touch事件是否继续向下传递。
2. dispatchTouchEvent方法只负责事件的分发,它拥有boolean类型的返回值,当返回为true时,顺序下发会中断。在上述例子中如果⑤的dispatchTouchEvent返回结果为true,那么⑥-⑦-③-④将都接收不到本次Touch事件。当一个Touch事件(触摸事件为例)到达根节点,即Acitivty的ViewGroup时,它会依次下发,下发的过程是调用子View(ViewGroup)的dispatchTouchEvent方法实现的。简单来说,就是ViewGroup遍历它包含着的子View,调用每个View的dispatchTouchEvent方法,而当子View为ViewGroup时,又会通过调用ViwGroup的dispatchTouchEvent方法继续调用其内部的View的dispatchTouchEvent方法。上述例子中的消息下发顺序是这样的:①-②-⑤-⑥-⑦-③-④。

3.onTouchEvent,这个作为 比较重要的一个事件,需要详讲,ViewGroup的onTouchEvent事件是什么时候处理的呢?当ViewGroup所有的子View都返回false时,onTouchEvent事件便会执行。由于ViewGroup是继承于View的,它其实也是通过调用View的dispatchTouchEvent方法来执行onTouchEvent事件。 一般对于touch 事件的 move down 等,放在  onTouchEvent 里面处理。

好的,知道了以上3个方法都是干什么的了,那么天下间的 所有滑动冲突都将迎刃而解, 首先,我们先来 解决一开始的问题,
scrollview  嵌套viewpager 导致 的, 我在上下滑动viewpager的时候,scrollview 没响应 , 简单!

解决的办法也很简单,重写父scrollview 的 拦截事件,给定一定的条件,决定touch事件是否向下传递,比如,我们重写 
scrollview 的  onInterceptTouchEvent 方法, 判定用户的手势,当手势仅仅是上下滑动的时候,直接return true,消耗掉此次的touch事件,如此一来,就不会传递给 下面的viewpager 让其消耗了,

或者重写子viewpager  的touch事件 ,给定一定条件,决定是否消耗此次 touch ,比如,我们重写viewpager  的 onTouchEvent方法,判定用户的手势,如果是横向移动,就返回 true 消耗此次事件, 如果是 竖直移动 就返回false ,表示把此次事件的决定权返回给 父的
scrollview 来处理,这样就解决了 传说中的 滑动冲突!!!!

有没有很6,自我感觉,真tm666666!










评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值