Android进阶-多个ViewPager嵌套时事件传递的处理

来源:互联网 发布:linux开启udp端口 编辑:程序博客网 时间:2024/06/05 17:51

Android进阶-多个ViewPager嵌套时事件传递的处理

先来看一下图:
复杂的UI框架图: 2.5, 2, 4
这里写图片描述
这里写图片描述
这里写图片描述
- 对事件响应的要求

  • 可以看出共有3个ViewPager(分别称为vpOut, vpMiddle, vpInner)和一个SlidingMenu
  • 其中,vpOut是不可以滑动的,它是跟随下面的RadioButtond的点击事件而改变的(实现方法是,继承ViewPager,重写onTouchEcent,并什么都不做)
    1. 侧滑菜单,仅在vpMiddle中的条目为第一条时,才可以滑动出来
      • 处理办法是, 监听vpMiddle的pageChange事件,并在第一个条目时,设置SlidingMenu可以滑出

    @Override    public void onPageSelected(int position) {        /*......*/        if (position == 0) {//只有在第一个页面, 侧边栏才允许出来            slidingMenu.setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN);         } else {            slidingMenu.setTouchModeAbove(SlidingMenu.TOUCHMODE_NONE);        }    }
    1. 对于最里层的vpInner(展示图片的), 外层的vpMiddle不应拦截他的滑动事件
      • 处理办法是,覆写dispatchTouchEvent()方法, 让父控件,给他处理滑动事件的机会

    @Override    public boolean dispatchTouchEvent(MotionEvent ev) {            getParent().requestDisallowInterceptTouchEvent(true);    //请求父控件给他机会                                                            }
    1. 继续vpInner的滑动进行处理
      • 从图可以看出,这个voInner是和ListView在一块的
        • 对于上下滑动,他应该响应,并让ListView进行滑动
        • 对于左滑动,当向左滑动到最后一张图片是,应对上一个ViewPager的页面切换,使其切换的下一页
        • 对于右滑动,当向左滑动到最后一张图片是,应对上一个ViewPager的页面切换,使其切换的上一页
        • 因此,可以在2的代码的基础上,继续对滑动事件进行处理

    @Override    public boolean dispatchTouchEvent(MotionEvent ev) {        switch (ev.getAction()) {        case MotionEvent.ACTION_DOWN:            getParent().requestDisallowInterceptTouchEvent(true);// 不要拦截,// 这样是为了保证ACTION_MOVE调用            startX = (int) ev.getRawX();            startY = (int) ev.getRawY();            break;        case MotionEvent.ACTION_MOVE:            int endX = (int) ev.getRawX();            int endY = (int) ev.getRawY();            if (Math.abs(endX - startX) > Math.abs(endY - startY)) {// 左右滑动                if (endX > startX) {// 右划                    if (getCurrentItem() == 0) {// 第一个页面, 需要父控件拦截                        getParent().requestDisallowInterceptTouchEvent(false);                    }                } else {// 左划                    if (getCurrentItem() == getAdapter().getCount() - 1) {// 最后一个页面,                                                                            // 需要拦截                        getParent().requestDisallowInterceptTouchEvent(false);                    }                }            } else {// 上下滑动                getParent().requestDisallowInterceptTouchEvent(false);            }            break;        default:            break;        }        return super.dispatchTouchEvent(ev);    }
  • 小结
  • 应避免这样的问题的出现
    • vpMiddle允许父控件,拦截其触摸事件
    • vpInner不允许父控件,拦截其触摸事件
    • 这时,就没有办法调和了, vpInner肯定是响应不了触摸事件的
    • 解决办法是换一种思路: 绕过事件传递的处理, 在一定条件下, 直接不最外层父控件的触摸事件,给干掉, 那么就ok了
0 0
原创粉丝点击