RecyclerView滚动异常求助:仿Instagram个人页布局问题
嘿,这个问题我之前做类似Instagram风格主页的时候也碰到过!核心就是NestedScrollView和RecyclerView的滚动事件冲突,再加上CoordinatorLayout的滚动行为没配置到位,导致RecyclerView没法正常滚动。咱们分两种情况来解决,看哪种更贴合你的需求:
解决方案一:移除NestedScrollView,让RecyclerView做主(推荐)
这种方案性能最好,因为RecyclerView本身就有视图复用机制,比NestedScrollView包裹RecyclerView流畅得多,尤其适合列表项较多的场景。
调整思路:
把个人信息区域做成RecyclerView的Header View,让整个滚动(Header+列表项)都由RecyclerView负责,同时给RecyclerView绑定CoordinatorLayout的滚动行为,和CollapsingToolbar联动。
修改后的布局代码:
<android.support.design.widget.CoordinatorLayout android:layout_width="match_parent" android:layout_height="match_parent"> <!-- 折叠工具栏区域 --> <android.support.design.widget.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <android.support.design.widget.CollapsingToolbarLayout android:layout_width="match_parent" android:layout_height="250dp" app:layout_scrollFlags="scroll|exitUntilCollapsed"> <!-- 折叠背景图(可选) --> <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="centerCrop" android:src="@drawable/profile_bg" app:layout_collapseMode="parallax"/> <!-- 固定在顶部的Toolbar --> <android.support.v7.widget.Toolbar android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" app:layout_collapseMode="pin"/> </android.support.design.widget.CollapsingToolbarLayout> </android.support.design.widget.AppBarLayout> <!-- 下拉刷新控件,包裹RecyclerView --> <android.support.v4.widget.SwipeRefreshLayout android:id="@+id/refresh_layout" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v7.widget.RecyclerView android:id="@+id/profile_recycler" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior" android:nestedScrollingEnabled="true"/> </android.support.v4.widget.SwipeRefreshLayout> </android.support.design.widget.CoordinatorLayout>
代码中添加Header:
在Activity/Fragment里给RecyclerView的Adapter添加个人信息Header:
// 初始化RecyclerView和Adapter RecyclerView recyclerView = findViewById(R.id.profile_recycler); MyProfileAdapter adapter = new MyProfileAdapter(postList); // 你的自定义Adapter // 加载个人信息Header布局 View headerView = LayoutInflater.from(this).inflate(R.layout.profile_info_header, recyclerView, false); // 给Header设置数据(比如头像、昵称、粉丝数等) headerView.findViewById(R.id.profile_avatar).setImageResource(R.drawable.avatar); headerView.findViewById(R.id.profile_name).setText("我的昵称"); // 添加Header到Adapter adapter.addHeaderView(headerView); // 设置RecyclerView布局管理器和Adapter recyclerView.setLayoutManager(new GridLayoutManager(this, 3)); // Instagram风格的网格布局 recyclerView.setAdapter(adapter);
解决方案二:保留NestedScrollView的兼容方案
如果你必须在RecyclerView上方保留独立的个人信息区域(不想做成Header),可以用这个方案,但要注意禁用RecyclerView的嵌套滚动,让NestedScrollView接管整个滚动事件。
修改后的布局代码:
<android.support.design.widget.CoordinatorLayout android:layout_width="match_parent" android:layout_height="match_parent"> <!-- 折叠工具栏区域 --> <android.support.design.widget.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <android.support.design.widget.CollapsingToolbarLayout android:layout_width="match_parent" android:layout_height="250dp" app:layout_scrollFlags="scroll|exitUntilCollapsed"> <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="centerCrop" android:src="@drawable/profile_bg" app:layout_collapseMode="parallax"/> <android.support.v7.widget.Toolbar android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" app:layout_collapseMode="pin"/> </android.support.design.widget.CollapsingToolbarLayout> </android.support.design.widget.AppBarLayout> <!-- 下拉刷新包裹NestedScrollView --> <android.support.v4.widget.SwipeRefreshLayout android:id="@+id/refresh_layout" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v4.widget.NestedScrollView android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <!-- 个人信息区域 --> <include layout="@layout/profile_info"/> <!-- 禁用自身嵌套滚动的RecyclerView --> <android.support.v7.widget.RecyclerView android:id="@+id/profile_recycler" android:layout_width="match_parent" android:layout_height="wrap_content" android:nestedScrollingEnabled="false"/> </LinearLayout> </android.support.v4.widget.NestedScrollView> </android.support.v4.widget.SwipeRefreshLayout> </android.support.design.widget.CoordinatorLayout>
关键注意点:
- 给NestedScrollView设置
app:layout_behavior="@string/appbar_scrolling_view_behavior",确保它能和CollapsingToolbar联动折叠。 - 给RecyclerView添加
android:nestedScrollingEnabled="false",避免它和NestedScrollView抢滚动事件。
最后提醒
方案一的性能和流畅度更好,是Instagram这类APP的标准实现方式;方案二更适合个人信息区域比较复杂、不方便做成RecyclerView Header的场景。选哪个就看你的具体需求啦~
内容的提问来源于stack exchange,提问作者Mohamed El Fwakhry
相关产品推荐
相关产品推荐

