当前位置: 代码迷 >> Android >> LinearLayout 和 RecyclerView 不会一起滚动
  详细解决方案

LinearLayout 和 RecyclerView 不会一起滚动

热度:124   发布时间:2023-08-04 10:52:16.0

我浏览了很多帖子,但找不到我需要的帖子。 我有一个带有 RecyclerView 的 LinearLayout,我希望两者都滚动。 现在,LinearLayout 是固定的,RecyclerView 是唯一一个滚动的。 我尝试使用nestedscrollview,但无法使其工作。 出于某种原因,recyclerview.adapter 使用nestedscrollview 中断。 任何的想法? 顺便说一句:我正在 Xamarin Android 中开发

这是我的布局

<LinearLayout 
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
    <LinearLayout
       android:layout_width="match_parent"
       android:layout_height="match_parent">
         ...
    </LinearLayout>
    <FrameLayout
       android:id="@+id/navigation"
       android:layout_width="match_parent"
       android:layout_height="match_parent" />
</LinearLayout>

然后我在框架布局中加载一个片段,其布局是:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ProgressBar
    android:id="@+id/spinner"
    style="?android:attr/progressBarStyleLarge"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal" />
<android.support.v4.widget.SwipeRefreshLayout
    android:id="@+id/refresher"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:scrollbars="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />
</android.support.v4.widget.SwipeRefreshLayout>
<TextView
    android:id="@+id/empty_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
</LinearLayout>

LinearLayouts本身不会滚动,它们只是为了轻松地以线性方式一个接一个地组织一个视图。 如果要滚动一个,则需要将其嵌套在ScrollView中。

但是,鉴于您要完成的工作,我不知道将RecyclerView嵌套在ScrollView中是否可以正常工作。 (我尚未确认)

您使用LinearLayout寻找的行为是什么? 是否应该包含页眉和页脚? 如果是这样,可以为RecyclerView创建唯一的ViewHolders(例如,一个用于标题,一个用于页脚,另一个用于常规内容),从而为您提供更好的服务。 然后,适配器根据其索引确定要显示哪种ViewHolder。 (例如0->页眉,n + 2->页脚,1:n-1->内容(偏移1))

如果您只是在寻找静态标头(即不随内容其余部分一起滚动的标头),则可以轻松实现:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:weightSum="5">

    <!-- Replace this with your header view -->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:text="Your Header" />

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="4" >

        <android.support.v4.widget.SwipeRefreshLayout
            android:id="@+id/refresher"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <android.support.v7.widget.RecyclerView
                android:id="@+id/recyclerView"
                android:scrollbars="vertical"
                android:layout_width="match_parent"
                android:layout_height="fill_parent" />
        </android.support.v4.widget.SwipeRefreshLayout>

        <ProgressBar
            android:id="@+id/spinner"
            style="?android:attr/progressBarStyleLarge"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:layout_centerHorizontal="true" />
    </RelativeLayout>
</LinearLayout>

这将为您提供一个标头视图,它将占包含视图总高度的1/5。 RecyclerView(包括其包含的视图和进度条)处于一个将包含包含的视图总高度的其余4/5的视图中。

如果我理解正确的话,您需要滚动 RecyclerView 的内容以及也放置在 LinearLayout 内的周围视图,就好像它们只是在一个滚动容器内一样。

要解决此问题,您可以使用 NestedScrollLayout。 使您的布局看起来与此类似:

<NestedScrollLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <ProgressBar
            android:id="@+id/spinner"
            style="?android:attr/progressBarStyleLarge"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal" />

        <android.support.v4.widget.SwipeRefreshLayout
            android:id="@+id/refresher"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <android.support.v7.widget.RecyclerView
                android:id="@+id/recyclerView"
                android:scrollbars="vertical"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent" />

        </android.support.v4.widget.SwipeRefreshLayout>

        <TextView
            android:id="@+id/empty_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

    </LinearLayout>

</NestedScrollLayout>

现在,您可以通过在代码中插入额外的一行来实现您的目标:

ViewCompat.setNestedScrollingEnabled(listRecyclerView, false);

在将 RecyclerViewAdapter 附加到 RecyclerView 后,必须添加此行。 滚动行为应该就像你想要的那样。

您可以在此处重新阅读此解决方案: :

我采用了他的方法来解决你的问题,因为作者更概括地描述了他的方法。

我希望这对您和其他遇到此问题的人有所帮助。

编辑:不幸的是,这种方法有两个我刚刚遇到的缺点。

首先它禁用 RecyclerView 的滚动,因此设置到 RecyclerView 的任何 ScrollListener 将不再触发。

其次,当您将setNestedScrollingEnabledfalse ,不再存在 RecyclerView 的好处。 您的 RecyclerView 无法使用此设置中的回收功能。 这意味着,列表中的所有项目都将在开始时直接呈现。 如果您的列表中有很多项目,这可能会导致您的应用程序性能不佳,因为它需要更长的时间来布置所有内容并且需要更多内存。

  相关解决方案