ViewPager嵌套HorizontalScrollView滑动冲突以及点击抖动问题解决

ViewPager嵌套HorizontalScrollView滑动冲突以及点击抖动问题解决

礼物弹窗

项目中有这样一个礼物弹窗,可选择角色的数量不固定,需要左右滑动,加上弹窗两个TAB可以左右滑动,所以存在滑动冲突。

弹窗主体使用viewpager,角色选择栏使用HorizontalScrollView,嵌套关系如下图所示。

礼物部分(忽略空态):
- ViewPager          //弹窗主体
    - RelativeLayout //礼物TAB
        - Gridview   //礼物列表
        - LinearLayout  //角色选择栏
            -TextView   //"送给"
            - HorizontalScrollView //水平滑动view
                -LinearLayout      //角色列表
        - BottomView  //底部复杂按钮

问题一:滑动冲突

如果不做任何处理,写完布局以后,HorizontalScrollView的左右滑动事件会被ViewPager吃掉,角色列表并不能滑动,就是滑动冲突了。

解决方案很简单,把ViewPager吃掉的触摸事件还给HorizontalScrollView。做几件事情:
- 找到触摸事件被吃掉之前的时机(方法)
- 判断触摸事件是否应该被HorizontalScrollVIew处理
- 如果是HorizontalScrollView的事件,就给它处理,否则按原有逻辑处理

1、吃掉触摸事件之前的时机就是 RelativeLayout的onInterceptTouchEvent方法。
2、判断是否交给HorizontalScrollView,只需要计算触摸位置是否为HorizontalScrollVIew

  //RelativeLayout
  @Override
  public boolean onInterceptTouchEvent(MotionEvent ev) {
    if (isTouchRole(ev)) { //判断点击了ScrollView
      //交给ScrollView处理
      mRoleListScrollView.onTouchEvent(ev);
      return false;
    }

    return super.onInterceptTouchEvent(ev);
  }

  //判断点击区域是否在HorizontalScrollView
  public boolean isTouchRole(MotionEvent ev) {
    RectF rect = calcViewScreenLocation(mRoleContainer);
    boolean isInViewRect = rect.contains(ev.getRawX(), ev.getRawY());

    return isInViewRect;
  }

  public static RectF calcViewScreenLocation(View view) {
    int[] location = new int[2];
    // 获取控件在屏幕中的位置,返回的数组分别为控件左顶点的 x、y 的值
    view.getLocationOnScreen(location);
    return new RectF(location[0], location[1], location[0] + view.getWidth(),
        location[1] + view.getHeight());
  }

问题二:部分机型点击HorizonScrollView时会抖动,或者滑动,如小米,三星等

经过调试打点发现,出问题的手机在onInterceptTouchEvent方法时,MotionEvent的Action均为ACTION_MOVE,而正常手机为ACTION_DOWN,这也很好的说明了ScrollView为什么会滑动。

所以再对onInterceptTouchEvent进行一些的处理,防止这种情况出现:

  @Override
  public boolean onInterceptTouchEvent(MotionEvent ev) {
    if (isTouchRole(ev)) {
      //适配
      switch (ev.getAction()){
        case ACTION_DOWN:
          break;
        case ACTION_UP:
          mRoleListScrollView.onTouchEvent(ev);
          break;
        case ACTION_MOVE:
          break;
      }
      return false;
    }

    return super.onInterceptTouchEvent(ev);
  }

猜你喜欢

转载自blog.csdn.net/qq_15602635/article/details/79223199
今日推荐