【问题标题】:RecycleView leaves empty space at the bottom because of toolbar由于工具栏,RecycleView 在底部留下空白空间
【发布时间】:2019-07-23 04:53:37
【问题描述】:

更新:

  • 实际问题是CoordinatorLayout 而不是RecycleView
  • 我没有使用RecycleView,而是在ScrollView 中尝试了TextView,这是同样的问题。
  • 如果您将Toolbar 用作ActionBar 并将CoordinatorLayout 与另一个ToolBar 用作底部滚动元素的粘性标题,则某些内容未对齐

原文:

我正在开发一个视图,该视图需要 Sticky 标头实现,底部有回收视图。我使用了Coordinator layout support,如此处所述。

什么是有效的:

  • 滚动列表上的粘滞视图。
    • 工具栏使用 layout_collapseMode = pinCollapsingToolbarLayout 使用 layout_scrollFlags = scroll|exitUntilCollapsed|snap 属性。
    • 具有行为app:layout_behavior="@string/appbar_scrolling_view_behavior"的回收视图

什么是问题:

  • 回收视图在底部留边距,它的大小与我用于粘性视图的Toolbar 相同。
  • 回收视图最后一项不显示,它需要额外的 bottom_margin 作为粘性工具栏视图的大小。

观察:

  • 如果我立即填充回收,那么它就可以工作。但是,如果延迟通知它,则会导致问题。
  • 更新。 在另一次试用和运行**中,我没有使用 Recycle,而是在 NestedScrollView.(PFA) 中放置了一个 TextView(此处未更新布局)
    • 在这里,我从 xml 添加了文本,延迟 2 秒后,只需添加更多文本,结果相同。
    • 这是再次占用下边距的布局。所以没有什么与回收视图相关的具体内容,CoordinatorLayout 似乎有些问题。

我尝试了多种可用的解决方案herehere,但都没有工作。

PFA,电流输出。

更新 PFA,尝试延迟文本视图。

这是布局文件。

<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/summaryAppBar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:id="@+id/main.collapsing"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="256dp"
                android:background="@drawable/fable_1"
                app:layout_collapseMode="parallax"
                app:layout_collapseParallaxMultiplier="0.3" />

            <!-- This is sticky header-->
            <androidx.appcompat.widget.Toolbar
                android:id="@+id/summaryToolBar"
                android:layout_width="match_parent"
                android:layout_height="72dp"
                android:layout_gravity="center"
                android:background="@android:color/white"
                android:padding="@dimen/common_layout_margin"
                android:visibility="visible"
                app:layout_collapseMode="pin"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light">

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

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:textSize="24sp"
                        android:text="Name" />

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_gravity="right"
                        android:textSize="24sp"
                        android:text="Offer"/>

                </FrameLayout>

            </androidx.appcompat.widget.Toolbar>

        </com.google.android.material.appbar.CollapsingToolbarLayout>

    </com.google.android.material.appbar.AppBarLayout>

   <!-- Bottom margin if I do't use then it does not display last child item. Wired but true in this case-->

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clipToPadding="false"
        android:visibility="visible"
        android:layout_marginBottom="72dp"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        tools:listItem="@layout/item_dessert" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

【问题讨论】:

  • 请分享您的代码
  • 您是否已将 : android:fitsSystemWindows="true" 添加到您的协调器视图中?
  • 是的,但是向上推动布局并导致操作栏从顶部切开。
  • 你没有设置android:layout_marginBottom="72dp"吗?
  • @PFuster 所以我在什么是问题部分添加了问题。删除甚至不解决底部空间问题。另请参阅观察部分,到目前为止我可以得出结论。

标签: android android-toolbar android-coordinatorlayout android-collapsingtoolbarlayout stickyrecycleview


【解决方案1】:

输入滚动时,RecyclerView 高度计算错误。这两个不同的例子只会增加问题的混淆,没有提供至少Java 代码。

只需从RecyclerView 中删除这一行:

android:layout_marginBottom="72dp"

这个属性用处不大,因为它是默认值:

android:visibility="visible"

不要像这样设置RecyclerView 高度:

android:layout_height="match_parent"

但要填满可用空间:

android:layout_height="0dp"
android:layout_weight="1.00"

这样RecyclerView 将始终适合,以防万一存在工具栏,无论是否 - 此工具栏不应该设置为粘性,因为这需要半心半意地“修复”布局。 BottomNavigationView 最终可能在那里有用,具体取决于该工具栏的用途。甚至找到了脚本的来源:CoordinatorBehaviorExample,它应该被归因,因为许可证需要它。

【讨论】:

  • 嗨马丁,我在布局部分添加了评论。关于权重属性,它不可能作为 CoordinatorLayout 的直接子级,尽管将 NestedScrollView 和 RecycleView 放入 LinearLayout 也没有任何区别。
  • 工具栏我用作粘性标题的一部分,在 GIF 中我用文本(名称和报价标签)显示。关于 BottomNavigationView,不确定如何解决它!
【解决方案2】:

你能试试下面的布局文件吗?我已经对其进行了测试,并且效果很好。您也可以从 recyclerview 中删除 marginButtom。

xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">


<androidx.coordinatorlayout.widget.CoordinatorLayout 
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">

<com.google.android.material.appbar.AppBarLayout
    android:id="@+id/summaryAppBar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <com.google.android.material.appbar.CollapsingToolbarLayout
        android:id="@+id/main.collapsing"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="256dp"
            android:background="@drawable/fable_1"
            app:layout_collapseMode="parallax"
            app:layout_collapseParallaxMultiplier="0.3" />

        <!-- This is sticky header-->
        <androidx.appcompat.widget.Toolbar
            android:id="@+id/summaryToolBar"
            android:layout_width="match_parent"
            android:layout_height="72dp"
            android:layout_gravity="center"
            android:background="@android:color/white"
            android:padding="@dimen/common_layout_margin"
            android:visibility="visible"
            app:layout_collapseMode="pin"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light">

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

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textSize="24sp"
                    android:text="Name" />

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="right"
                    android:textSize="24sp"
                    android:text="Offer"/>

            </FrameLayout>

        </androidx.appcompat.widget.Toolbar>

        </com.google.android.material.appbar.CollapsingToolbarLayout>

    </com.google.android.material.appbar.AppBarLayout>



    <androidx.recyclerview.widget.RecyclerView
    android:id="@+id/recyclerView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clipToPadding="false"
    android:visibility="visible"
    android:layout_marginBottom="72dp"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:listItem="@layout/item_dessert" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>
</RelativeLayout>

【讨论】:

  • 添加一个相对布局作为父布局解决了这个大问题。谢谢吉腾。
【解决方案3】:

我相信 CoordinatorLayout(可能是 AppBarLayoutCollapsingToolbarLayout - 不确定是哪个组件)由于粘性工具栏记录了 CollapsingToolbarLayout 的不正确高度。如果在初始布局之前或之后添加项目,行为会有所不同。

尝试以下方法:

  1. RecyclerView 的 XML 中删除 android:layout_marginBottom="72dp"
  2. android:minHeight="72dp" 添加到CollapsingToolbarLayout 的XML

由于您的粘性工具栏设置为72dp,因此可以将minHeight 设置为72dp

如果您对此有任何疑问,请返回此处。


这是使用 NestedScrollView 和上述更改的布局的快速演示。

更新:我已经使用 RecyclerView 解决了这个问题,它显示了同样的问题。演示项目显示问题和修复在GitHub

代码如下:

MainActivity.java

public class MainActivity extends AppCompatActivity {  
    // Set to true to break the layout; false for it to work.  
    // The setting of this flag should only matter for the 
    // layout activity_not_working.  
    private boolean mBreakIt = true;  

    //    private int mLayoutToUse = R.layout.activity_not_working;  
    private int mLayoutToUse = R.layout.activity_working;  

    private LinearLayout mLayout;  

    @Override  
  protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(mLayoutToUse);  

        mLayout = findViewById(R.id.linearLayout);  
        if (mBreakIt) {  
            mLayout.post(new Runnable() {  
                @Override  
  public void run() {  
                    addViews();  
                }  
            });  
        } else {  
            addViews();  
        }  
    }  

    private void addViews() {  
        for (int i = 0; i < 50; i++) {  
            TextView tv = new TextView(MainActivity.this);  
            tv.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,  
                    ViewGroup.LayoutParams.WRAP_CONTENT));  
            tv.setText("TextView #" + (i + 1));  
            mLayout.addView(tv);  
        }  
    }  
}

activity_working.xml

<androidx.coordinatorlayout.widget.CoordinatorLayout 
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/summaryAppBar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:id="@+id/main.collapsing"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:minHeight="72dp"
            app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="256dp"
                android:background="@drawable/beach"
                app:layout_collapseMode="parallax"
                app:layout_collapseParallaxMultiplier="0.3" />

            <!-- This is sticky header-->
            <androidx.appcompat.widget.Toolbar
                android:id="@+id/summaryToolBar"
                android:layout_width="match_parent"
                android:layout_height="72dp"
                android:layout_gravity="center"
                android:background="@android:color/white"
                android:padding="@dimen/common_layout_margin"
                android:visibility="visible"
                app:layout_collapseMode="pin"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light">

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

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="Name"
                        android:textSize="24sp" />

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_gravity="right"
                        android:text="Offer"
                        android:textSize="24sp" />

                </FrameLayout>

            </androidx.appcompat.widget.Toolbar>

        </com.google.android.material.appbar.CollapsingToolbarLayout>

    </com.google.android.material.appbar.AppBarLayout>

    <!-- Bottom margin if I do't use then it does not display last child item. Wired but true in this case-->
    <!-- Removed following: -->
    <!--android:layout_marginBottom="72dp"-->

    <androidx.core.widget.NestedScrollView
        android:id="@+id/nestedScrollView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/holo_blue_light"
        android:visibility="visible"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        app:layout_insetEdge="bottom"
        tools:listItem="@layout/item_dessert">

        <LinearLayout
            android:id="@+id/linearLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

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

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

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

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


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

</androidx.coordinatorlayout.widget.CoordinatorLayout>

activity_not_working.xml

<androidx.coordinatorlayout.widget.CoordinatorLayout 
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/summaryAppBar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:id="@+id/main.collapsing"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="256dp"
                android:background="@drawable/beach"
                app:layout_collapseMode="parallax"
                app:layout_collapseParallaxMultiplier="0.3" />

            <!-- This is sticky header-->
            <androidx.appcompat.widget.Toolbar
                android:id="@+id/summaryToolBar"
                android:layout_width="match_parent"
                android:layout_height="72dp"
                android:layout_gravity="center"
                android:background="@android:color/white"
                android:padding="@dimen/common_layout_margin"
                android:visibility="visible"
                app:layout_collapseMode="pin"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light">

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

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="Name"
                        android:textSize="24sp" />

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_gravity="right"
                        android:text="Offer"
                        android:textSize="24sp" />

                </FrameLayout>

            </androidx.appcompat.widget.Toolbar>

        </com.google.android.material.appbar.CollapsingToolbarLayout>

    </com.google.android.material.appbar.AppBarLayout>

    <!-- Bottom margin if I do't use then it does not display last child item. Wired but true in this case-->
    <!-- Removed following: -->
    <!--android:layout_marginBottom="72dp"-->

    <androidx.core.widget.NestedScrollView
        android:id="@+id/nestedScrollView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginBottom="72dp"
        android:background="@android:color/holo_blue_light"
        android:visibility="visible"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        app:layout_insetEdge="bottom"
        tools:listItem="@layout/item_dessert">

        <LinearLayout
            android:id="@+id/linearLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

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

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

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

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


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

</androidx.coordinatorlayout.widget.CoordinatorLayout>

【讨论】:

  • 我试过这个,但在我的情况下它是同样的问题。请注意,我已经将工具栏设置为操作栏。我还在继续,很快就会更新。
【解决方案4】:

嘿,你在那里设置了marginBottom 属性。删除它。这就是错误所在。 RecyclerView 的代码应该是:

<androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clipToPadding="false"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        tools:listItem="@layout/item_dessert" />

【讨论】:

  • 嗨 Gourav,由于一些奇怪的未知原因需要它,我在 什么是问题部分 和布局部分评论中添加了问题。请参考。
  • android:clipToPadding="false" 是我要找的... +1
【解决方案5】:

我认为在添加新数据和通知适配器时可能会出现问题。

您应该从 notifyDataSetChanged() 更改为 notifyItemInserted(index)

更多关于notifyItemInserted(index)here的文档。

希望对你有帮助。

【讨论】:

  • Hiren,这有助于在一定程度上解决问题,但原始问题仍然存在。请参考更新后的帖子。
猜你喜欢
  • 1970-01-01
  • 2015-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-01
  • 2018-12-07
相关资源
最近更新 更多