ViewPager嵌套HorizontalScrollView滑动冲突以及点击抖动问题解决
程序员文章站
2024-01-28 18:49:28
...
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);
}
下一篇: MySQL无法启动服务