解决NestedScrollView中,在子View上滑动不触发滚动事件,却触发点击事件

问题描述


1. 整体布局

解决NestedScrollView中,在子View上滑动不触发滚动事件,却触发点击事件_第1张图片

为了实现上滑悬停的TabView,使用了CoordinatorLayout,每一个Tab里都是一个NestedScrollView。

2. 问题布局

解决NestedScrollView中,在子View上滑动不触发滚动事件,却触发点击事件_第2张图片

在如图所选的区域滑动(RelativeLayout),只会触发图片的点击事件,不会触发CoordinatorLayout的滑动事件使Tab上方的布局展开或者收起。而在其它区域(LinearLayout)滑动则会正常滚动

3. 截图

分析


1. 事件分发机制

遇到滑动冲突的问题,第一反应自然是Android的事件分发机制。 
先来复习下: 
解决NestedScrollView中,在子View上滑动不触发滚动事件,却触发点击事件_第3张图片

从源码ViewGroup来分析一个L控件的事件传递过程,引用自《Android深入透析》之Android事件分发机制。

可是因为子布局(RelativeLayout)中需要完成点击事件,所以倘若父布局(LinearLayout)拦截了触摸事件之后,子布局上滑动事件的确能正确相应了,但是点击操作就无法实现了。

2. 面向Stackoverflow编程

在尝试了事件拦截,自定义view等一系列尝试之后,我决定想谷爹求助。 
最后我找到了这个:Scroll doesn’t work in NestedScrollView when try to scroll from views with click events。 
解决NestedScrollView中,在子View上滑动不触发滚动事件,却触发点击事件_第4张图片

也就是说,不能滚动的原因是你滚动布局内的布局长度不够

让我们来复现一下: 
解决NestedScrollView中,在子View上滑动不触发滚动事件,却触发点击事件_第5张图片

注意红箭头处的间隙,可以看到LinearLayout的长度是没有撑满屏幕的。

3. 解决办法

setMinimumHeight给NestedScrollView内的子布局设置最小高度,这里最好通过代码计算出这个高度的值。

 
  
  1. DisplayMetrics displaymetrics = new DisplayMetrics();
  2. getBaseActivity().getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
  3. int screenHeight = displaymetrics.heightPixels;
  4. int actionBarHeight = 0;
  5. TypedValue tv = new TypedValue();
  6. if (getBaseActivity().getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) {
  7. actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data,getResources().getDisplayMetrics());
  8. }
  9. view.setMinimumHeight(screenHeight - actionBarHeight);

总结


Google大法好!Stackoverflow大法好!

你可能感兴趣的:(移动开发)