事件分发机制的再整理

        分析的对象为:MotionEvent;

        三个很重要的方法:dispatchonTouchEvent()(事件分发)、onInterceptTouchEVent()(事件拦截)、onTouchEvent()(事件处理);
        传递规则:当一个点击事件发生时候,传递顺序依照Activity->window->顶级的View;对于一个ViewGroup来说,点击事件首先也肯定会传递给它的dispatchTouchEvent()方法,dispatchTouchEvent()方法返回值由当前View的onTouchEvent()返回值以及子View的child.dispatchTouchEvent()共同决定,伪代码如下:
        public boolean diapatchTouchEvent(MotionEvent e)
        {
            boolean consume = false;
            if(onInterceptTouchEVent()){
                 consume = onTouchEvent();
            }else{
                   consume = child.dispatchTouchEvent();
             }
            return consume;
         }
       在dispatchTouchEvent()方法中调用onInterceptTouchEvent()方法,如果onInterceptTouchEvent()方法返回true表示当前View拦截该事件onTouchEvent()方法被调用,如果当前View的onInterceptTouchEvent()方法返回false表示当前View不拦截该事件,子View的dispatchTouchEvent()方法会被调用。

        如果当前View的onTouchEvent()方法被调用,如果返回false,当前View的父容器的onTouchEvent()方法会被调用,返回true表示处理当前事件,一旦当前View的onTouchEvent()被调用(开始处理事件)如果它的Action_DOWN事件不消耗(onTouchEvent()返回false),那么同一个事件的的其他事件都不会交给它处理,如果当前View不消耗除ACTION_DOMN外的其他事件,当前事件就会消失,并且父View的onTouchEvent()方法也不会被调用最终会传递给Activity处理。
当前View一旦决定拦截事件,该事件序列所有办法都会交给当前View处理。则在该事件序列中不存在onInterceptTouchEvent()不会再次被调用,
注意一点是View中是没有onInterceptTouchEvent()方法一旦点击事件传递给它,它就会调用onTouchEvent()方法就会被调用。子View可以通过getParent().DisallowInterceptTouchEvent()方法父View事件分发过程,但是Action_down事件除外。

        以上是个人通过看书以及网上资料的一点小总结,下面来结合最近的一个按理来具体分析下。其中,项目博客地址:个人csdn客户端的实现

        先来看UI设计图:


-存在问题1:一级ViewPager与SlidingMenu滑动时间冲突问题
--原因:一级ViewPager不需要滑动,通过底部Tab切换页面(ViewPager天然支持滑动)
--决解办法:(1)重写ViewPager的onTouchEvent()方法(是否处理时间)让它直接return false不处理事件;
            (2)重写ViewPager的onInterceptTouchEvent()方法(是否拦截事件)直接return false不拦截事件;

-存在问题2:ViewPagerIndicator向右滑动使侧边栏滑出(要求此时侧边栏不能出来)
--原因:ViewPagerIndicator向右滑动事件与上层控件SlidingMenu事件冲突
--尝试的解决办法:(1)重写ViewPagerIndicator(TabPagerIndicator.java)控件的disPatchTouchEvent()(是否分发事件) 在该方法中调用getParent().requestDisallowIntercepTouchEvent(true)请求父控件(SlidingMenu)不要拦截事件;

-存在问题3:二级ViewPager向右滑动(HomePager中中创建的子Pager,与ViewPagerIndicator是并集关系)使侧边栏出来
--原因:同上
--解决办法:(1)前期重写ViewPager控件的disPatchTouchEvent()方法(同上)
(2)后面发现和子ViewPager又出现事件冲突(原因及解决办法后面分析)

-存在问题4:三级Viewpager向右滑动与侧边栏冲突(原因和解决办法和上面类似)

-存在问题5:三级ViewPager在第一个页面的除第一个pager处向右滑动直接使侧边栏滑出(预期效果是:头条子Pager间切换)
--原因:设计代码重构问题-在第一个页面二级ViewPager请求父控件拦截事件,而此时三级ViewPager还有事件要处理请求父控件不要拦截时间形成事件冲突。
--解决办法:(1)二级ViewPager用原生的ViewPager,并设置页面的滑动监听onPagerChangeListener,监听第一个页面滑动事件并调用SlidingMenu提供的打开和关闭侧边栏方法;
(2)三级VIewPager重写dispatchTouchEvent()方法根据上下滑动左右滑动以及调用getcount()方法判断当前是处于哪一个子Pager判断是否请求父控件拦截事件;

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值