android - 将 RecyclerView 放在 NestedScrollView 中,为所有项目调用 onBindView

标签 android android-recyclerview

我有两个 RecyclerViews 垂直放置在 LinearLayout 中。我需要使它们都可滚动,这就是为什么我将 LinearLayout 放在 NestedScrollView

中的原因

这是我的布局文件。

<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:scrollbars="none">

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/featured_list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <android.support.v7.widget.RecyclerView
        android:id="@+id/all_topic_list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</LinearLayout>

另外,我在 Java 代码中禁用了嵌套滚动。

disableNestedScrolling(findViewById(R.id.all_topic_list));
disableNestedScrolling(findViewById(R.id.featured_list));

我的RecylerView库版本是26.1.0

这完美地工作,但是 onBindViewHolder 方法被调用用于列表中的所有项目。理想情况下,只应为列表中的可见项调用它。

我认为问题的发生是因为我将 wrap_content 提供给 RecyclerView。关于 this 的很多答案问题表明该问题已在 v23.2.1 中解决,但我已经在使用 v26.1.0。如何解决这个问题?

最佳答案

我遇到了完全相同的问题。 RecyclerViews 不应放置在具有相同滚动方向的滚动容器内。 View 回收仅在高度设置为 MATCH_PARENT 时有效。

根据 NestedScrollView 内部内容的复杂性和 RecyclerView 项的预期数量:

  1. 忽略这个问题。如果只有几个简单的项目,你可以 根本不需要查看回收。

    当我遇到这个问题时,我分析了其他流行应用程序的布局:例如,WhatsApp 仅在某些部分使用了 RecyclerViews(或 ListViews with view recycling)他们的应用程序。

    特别是,this group settings screen有数百个可能的项目由多个 ListViews 组成,被 ScrollView 包裹,没有任何 View 回收。

  2. NestedScrollView 替换为单个 ReyclerView with multiple item types并将所有可滚动内容放入其中。如果您需要 View 回收,这是要走的路。

    请注意,您还必须将 NestedScrollView 中的所有其他内容(页眉和页脚、间距)转换为具有自己的 ViewHoldersRecyclerView 项目。

    如果设置相当简单,我建议您按照上面的链接在没有其他库的情况下实现它。


有几个不同的库可用于解决您的问题(所有库都遵循第二种方法,使用单个 RecyclerView),但大多数都带有许多您可能不需要的额外功能:

RendererRecyclerViewAdapter

它带有一个 ViewRenderer/ViewModel interface ,这就像一个 单个项目类型的“部分”RecyclerView。你会创造一个 针对每种项目类型,然后将它们注册到单个适配器中。

Epoxy

由 airbnb 创建并在其应用程序中大量使用的库/框架。 他们有很多可滚动的内容(类似于网页) 许多不同的项目类型。环氧树脂还有助于组成 页面上的不同项目,并在 内容或其顺序发生变化。如果您只需要一个屏幕就太多了。

Litho

由 Facebook 创建的完整 UI 框架,带有自己的渲染引擎,可替代 xml 布局等。据我了解,它允许您处理大量项目(如 Facebook 时间线),并且 View 回收是自动处理的。与 Epoxy 一样,只有当您的应用包含无限滚动和大量不同项目类型并且您确实需要这种性能时,您才会使用它。


我尝试了 Epoxy 和 RendererRecyclerViewAdapter,但毕竟我创建了自己的多项目类型适配器。它可以用不到 100 行代码创建。

关于android - 将 RecyclerView 放在 NestedScrollView 中,为所有项目调用 onBindView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50655664/

相关文章:

android - 如何对 session 室数据进行分类?

java - 如何使用 Android Studio 编写具有指定索引范围的短数组?

java - Libgdx - 带延迟的随机颜色变化

java - 从 Arraylist 动态添加 View

java - Butterknife 不适用于适配器类

android - 适配器 notifyDataSetChanged() 上的 NullPointerException。我需要做什么?

java - 如何检测 Recyclerview 项目是否被刷?

android - 在 Android 上使用 ClassNotFoundException 首次打开时 Flutter 应用程序崩溃

java - 如何从 ViewPager (TabLayout) 内的 Activity 动态更改工具栏

android - 服务停止时 Widget 的 PendingIntent 丢失