Android嵌套滑动的处理

开发中,遇到了一个非常复杂的页面。

最外层是一个ViewPager,内层一个ScrollView,上方是主内容部分的Layout,下方是一个可以悬停的Tabbar,以及一个ViewPager,下方ViewPager中还有ScrollView和RecyclerView,并且继承了上拉加载控件SmartRefreshLayout。

由于嵌套了太多的滚动,此时在滑动时出现了非常多不跟手的问题。甚至有时出现内层可滑动,但是外层还没有滑到底,滑动非常不连贯。为了解决这个问题,这次使用了v4包中的NestedScrollView,它可以很好的帮助我们解决滑动问题。

首先自定义一个滑动控件继承自NestedScrollView,复写onNestedPreScroll方法,这个方法是流畅滑动的关键,可以对每次的滑动进行消耗控制。即,当内部滑动到底时,如果外部可以进行滚动,那么在消耗完毕内部的滑动距离之后,开始对外部ScrollView进行滚动。

该方法的参数意义如下:

  • target:当前发生滚动的View
  • dx:横向滚动的距离
  • dy:纵向滚动的距离
  • consumed:父布局需要消耗的X,Y距离
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

@Override
public void onNestedPreScroll(View target, int dx, int dy, int[] consumed) {
//上推
boolean hiddenTop = dy > 0 && getScrollY() < headerHeight;
//下拉
boolean canScrollVertically;
//如果里面内嵌了SmartRefreshLayout,需要判断内部嵌套的RecyclerView是否可以滑动
if (target instanceof SmartRefreshLayout) {
canScrollVertically = ((SmartRefreshLayout) target).getChildAt(0).canScrollVertically(-1);
} else {
canScrollVertically = target.canScrollVertically(-1);
}

boolean showTop = dy < 0 && getScrollY() > 0 && !canScrollVertically;

//由外层ScrollView消耗事件
if (hiddenTop || showTop) {
scrollBy(0, dy);
consumed[1] = dy;
}
}

@Override
public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes) {
return isEnabled() && (nestedScrollAxes & ViewCompat.SCROLL_AXIS_VERTICAL) != 0;
}

参考:

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×