Android ScrollView 嵌套 RecyclerView 问题
01.可能出现的问题
- 实际开发中,要实现在NestedScrollView中嵌入一个或多个RecyclerView。这一做法通常会导致如下几个问题
- 页面滑动卡顿
- ScrollView高度显示不正常
- RecyclerView内容显示不全
- NestedScrollView滚动不到顶部
02.滑动卡顿问题
若只存在滑动卡顿这一问题,可以采用如下两种简单方式快速解决。
第一种方法:利用RecyclerView内部方法
- 需要设置方法如下所示。这个方法主要是设置RecyclerView不处理滚动事件,全部交由ScorllView去处理,这样就解决了滑动卡顿的问题。
1
2recyclerView.setHasFixedSize(true);
recyclerView.setNestedScrollingEnabled(false);- 其中,setHasFixedSize(true)方法使得RecyclerView能够固定自身size不受adapter变化的影响;而setNestedScrollingeEnabled(false)方法则是进一步调用了RecyclerView内部NestedScrollingChildHelper对象的setNestedScrollingeEnabled(false)方法,如下
1
2
3
4
5
6
7
8
9
10
11
12
13public void setNestedScrollingEnabled(boolean enabled) {
this.getScrollingChildHelper().setNestedScrollingEnabled(enabled);
}
public void setNestedScrollingEnabled(boolean enabled) {
if (this.mIsNestedScrollingEnabled) {
//NestedScrollingChildHelper对象通过该方法关闭RecyclerView的嵌套滑动特性
ViewCompat.stopNestedScroll(this.mView);
}
this.mIsNestedScrollingEnabled = enabled;
}第二种方法:重写LayoutManager。
- RecyclerView的垂直滑动始终返回false,其目的同样是为了限制自身的滑动
1
2
3
4
5
6LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this) {
@Override
public boolean canScrollVertically() {
return false;
}
};
03.解决卡顿和显示问题
有时候上面说的几种情况都存在,或者说都需要解决,那么综合解决办法如下所示:
- 页面滑动卡顿
- ScrollView高度显示不正常
- RecyclerView内容显示不全
- NestedScrollView滚动不到顶部
第一种解决办法
设置recyclerView不处理滚动事件,并且在布局中嵌套一层LinearLayout/RelativeLayout解决焦点抢占问题。
网上有方案说是因为RecyclerView抢了焦点,自动滑动,只需要在xml页面在最顶层的View加入下面代码。发现并不好使!
1
2android:focusableInTouchMode="true"
android:focusable="true"设置descendantFocusability属性。使用网上的方法一种是使用 RelativeLayout 包裹 RecyclerView 并设置属性:android:descendantFocusability=”blocksDescendants”
- android:descendantFocusability=”blocksDescendants”,该属>性是当一个view 获取焦点时,定义 ViewGroup 和其子控件直接的关系,常用来>解决父控件的焦点或者点击事件被子空间获取。
- beforeDescendants: ViewGroup会优先其子控件获取焦点
- afterDescendants: ViewGroup只有当其子控件不需要获取焦点时才获取焦点
- blocksDescendants: ViewGroup会覆盖子类控件而直接获得焦点
1
2
3
4
5
6
7
8
9
10<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:descendantFocusability="blocksDescendants">
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_hot_review"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:foregroundGravity="center" />
</RelativeLayout>注意,之后尝试不用嵌套布局也可以实现滚动冲突问题
1
2
3
4
5<android.support.v7.widget.RecyclerView
android:id="@+id/rv_hot_review"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:descendantFocusability="blocksDescendants" />
04.使用嵌套建议
- 尽管我们能够采用多种方式解决ScrollView嵌套RecyclerView所产生的一系列问题,但由于上述解决方式均会使得RecyclerView在页面加载过程中一次性显示所有内容,因此当RecyclerView下的条目过多时,将会对影响整个应用的运行效率。基于此,在这种情况下我们应当尽量避免采用ScrollView嵌套RecyclerView的布局方式