ScrollView里面的RecyclerView,有些item不显示

RecyclerView inside ScrollView, some items are not shown

我在 ScrollView 中有一个 RecyclerView 是这样的:

<ScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!--other stuff-->

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

        <android.support.v7.widget.RecyclerView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:visibility="gone"/>

    </LinearLayout>

    <!--other stuff-->

</ScrollView>

RecyclerView的项目是一个RelativeLayout,里面有一个EditText等视图。 RelativeLayoutEditTextlayout_height都是wrap_content。用户可以输入 EditText 没有任何限制 length/lines 这样每个项目的高度都不同。

然后我发现 Adapter returns 中的 getItemCount() 是真实值,但 onBindViewHolder() 被调用的次数错误(少于应有的次数),因此不足以显示所有项目。

我发现只有写recyclerView.setNestedScrollingEnabled(false)才会出现这种情况。但我不能删除这条线。因为如果我这样做,RecyclerView 将不会平滑滚动并且与 ScrollViewScrollView 本身的其他视图不和谐。

这发生在 6.0 而不是 4.1。

我在这个页面上与 Google 进行了交流:https://code.google.com/p/android/issues/detail?id=213914,他告诉我这是 RecyclerView 的错误修复。您可以访问该页面,以便更好地理解问题和我的目标(有一个小示例项目可以在那里显示问题)。我现在也不同意他的看法,我想解决这个问题。请帮忙,提前谢谢你。

我自己找到了解决方案:将ScrollView替换为NestedScrollView并保留recyclerView.setNestedScrollingEnabled(false)。我不知道这是否是 NestedScrollView 的目的,但它确实有效。

注意:

  1. NestedScrollView 不是 ScrollView 的子代,而是 FrameLayout 的子代。
  2. 这个解决方案也会带来一些自我模拟的错误adjustResize

最佳解决方案是将 multiple Views 保留在 Single View / View Group 中,然后将那个视图保留在 SrcollView 中。

格式 -

<ScrollView> 
  <Another View>
       <RecyclerView>
       <TextView>
       <And Other Views>
  </Another View>
</ScrollView>

例如

<ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView           
              android:text="any text"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"/>


        <TextView           
              android:text="any text"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"/>
 </ScrollView>

另一个例子。具有多个视图的 ScrollView

<ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:orientation="vertical"
            android:layout_weight="1">

            <androidx.recyclerview.widget.RecyclerView
                android:id="@+id/imageView"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="#FFFFFF"
                />

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

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/CategoryItem"
                    android:textSize="20sp"
                    android:textColor="#000000"
                    />

                <TextView
                    android:textColor="#000000"
                    android:text="₹1000"
                    android:textSize="18sp"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"/>
                <TextView
                    android:textColor="#000000"
                    android:text="so\nugh\nos\nghs\nrgh\n
                    sghs\noug\nhro\nghreo\nhgor\ngheroh\ngr\neoh\n
                    og\nhrf\ndhog\n
                    so\nugh\nos\nghs\nrgh\nsghs\noug\nhro\n
                    ghreo\nhgor\ngheroh\ngr\neoh\nog\nhrf\ndhog"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"/>

             </LinearLayout>

        </LinearLayout>

</ScrollView>

在我的例子中,我用 RelativeLayout 替换了 LineaLayout,它解决了问题,所有项目都显示了。

答案是:

androidx.core.widget.NestedScrollView

第一步,需要在XML中创建NestedScrollView元素:

<androidx.core.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent">

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

    // RecyclerViews should be located here

    </LinearLayout>
</androidx.core.widget.NestedScrollView>

接下来,将以下属性添加到 recyclerView:

android:overScrollMode="never"

然后,recyclerView 将如下所示:

<androidx.recyclerview.widget.RecyclerView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:overScrollMode="never" />

最后整个布局如下图,你可以在LinearLayout中添加其他材质:

<androidx.core.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        <androidx.recyclerview.widget.RecyclerView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:overScrollMode="never" />
        // other materials
    </LinearLayout>
</androidx.core.widget.NestedScrollView>

庆祝......;)