冲突解决实战
子控件部分接管型
-
场景:SwipeRefreshLayout --> ScrollView --> ViewPager,这种布局场景很常见,多见于应用的首页,如美团。
-
分析冲突点:ScrollView的上下滑动与ViewPager的左右滑动原本是不冲突的,但是加入了SwipeRefreshLayout之后,事件场景就变得复杂。当滑动ViewPager的时候,很容易就触发了SwipeRefreshLayout的下来刷新。
-
解决思路:因为ViewPager只涉及X轴方向上的滑动,所以我们在MotionEvent_ACTION_MOVE的时候去动态的判断X周方向上是否超过了我们设定的阈值,这个值我们可以自定义,也可以去拿系统的这个值
mTouchSlop = ViewConfigurationCompat.getScaledPagingTouchSlop(configuration);
上下滑动与上下滑动的冲突型
ScrollView嵌套ListView
-
网上的解决思路分析:
- 根据展示数据的个数乘以每一个Item的高度,计算出ListView的总体高度,然后动态的设置ListView的高度
- 复写ListView的onMeasure(int widthMeasureSpec, int heightMeasureSpec)方法,让ListView完全展开
这两种方式最突出的缺陷在于ListView的子控件不能复用,容易造成OOM。
-
分析冲突点:嵌套之后ListView的高度无法完全显示,且两者存在事件冲突
-
解决思路:无法显示,复用的问题我们需要在布局中明确的设置ListView的高度。冲突根据ScrollView的状态和ListView的状态共同决定,冲突的解决选择在子View的onTouch()中解决。
- ScrollView在未滑动到底部时候,如果点击并滑动ListView时候,ListView是不能滑动的,不禁止。
- 如果ScrollView滑动到底部,且ListView已经到顶部,继续下拉ListView,其实会拉动ScrollView,不禁止。
- 如果ScrollView滑动到底部,用户向上滑,ListView滑动,禁止ScrollView截断点击事件能力
- 在scroll里面
setOnTouchListener
// 判断 scrollView 当前滚动位置在顶部
if(scroll_View.getSrollY == 0){
isSvToBottom = true;
}