CoordinatorLayout中底部导航栏遮盖了RecyclerView

23
我尝试使用Google支持库中的BottomNavigationView与Framelayout一起使用我的碎片。
这是我的代码。
<?xml version="1.0" encoding="utf-8"?>

<android.support.design.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"
android:fitsSystemWindows="true"
tools:context="com.bottombarnavigation.MainActivity">

<android.support.design.widget.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/AppTheme.AppBarOverlay">

  <include layout="@layout/toolbar"/>

</android.support.design.widget.AppBarLayout>

<include layout="@layout/content_main" />

<android.support.design.widget.BottomNavigationView
    android:background="#fcfcfc"
    android:id="@+id/bottom_navigation"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom|end"
    app:menu="@menu/bottom_navigation" />

</android.support.design.widget.CoordinatorLayout>

当我在Fragment中填充我的RecyclerView时,它的内容被BottomNavigationView覆盖了。

输入图像描述

我不知道为什么会出现这种情况。我查看其他人的教程并且它可以正常工作。

编辑 这是我的content_main.xml文件

<?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout 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"
    android:background="@android:color/white"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="com.bottombarnavigation.MainActivity"
    tools:showIn="@layout/activity_main">


<FrameLayout
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"></FrameLayout>
</RelativeLayout>

尝试使用此链接。我认为缺少属性app:layout_anchor和app:layout_anchorGravity。 - Dmitriy Kaluzhin
@DmitriyKaluzhin 我刚试了一下,结果是一样的。RecyclerView 的内容仍然在 BottomNavigationView 后面。 - EggRollMan
你找到这个问题的答案了吗? - Navid Eivazzadeh
9个回答

27

这是我的解决方案,对我来说有效。

我的布局与你几乎相同,我将BottomNavigationView移出了CoordinatorLayout,因为我不需要任何动画效果。 我将BottomNavigationView与父视图底部对齐,并在CoordinatorLayout中添加了layout_above,让它位于BottomNavigationView之上但填充整个屏幕。

通过这种配置,我修复了重叠问题,希望这能对你有所帮助。

这是我的布局。

    <RelativeLayout         
            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"
            tools:context=".ui.activities.MainActivity">

        <android.support.design.widget.CoordinatorLayout
                android:id="@+id/main_coordinator"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:fitsSystemWindows="true"
                android:layout_above="@+id/dashboard_navigation">

            <android.support.design.widget.AppBarLayout
                    android:id="@+id/main_appbar"
                    android:layout_width="match_parent"
                    android:layout_height="?attr/actionBarSize"
                    android:elevation="16dp">

                    <android.support.v7.widget.Toolbar
                        android:id="@+id/dashboard_toolbar"
                        android:layout_width="match_parent"
                        android:layout_height="?attr/actionBarSize"
                        android:background="@color/colorPrimary"/>
            </android.support.design.widget.AppBarLayout>

            <FrameLayout
                    android:id="@+id/main_frame_layout"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"/>

        </android.support.design.widget.CoordinatorLayout>

        <android.support.design.widget.BottomNavigationView
                android:id="@+id/dashboard_navigation"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_alignParentBottom="true"
                android:background="@color/colorPrimaryDark"
                app:itemTextColor="@color/colorAccent"
                app:menu="@menu/menu_main"/>
    </RelativeLayout>

2
浪费了很多时间来修复这个问题,最终一个如此简单的技巧解决了问题。感谢分享... - Rinav

6

CoordinatorLayout 最有用的功能之一是视图闪避。

CoordinatorLayout 的子视图可以被指定为插入边缘。任何您指定为闪避同一边缘的其他子视图都将被调整以适应。

在您的情况下,可以按照以下步骤进行:

<android.support.design.widget.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/AppTheme.AppBarOverlay">

  <include layout="@layout/toolbar"/>

</android.support.design.widget.AppBarLayout>

<include 
    layout="@layout/content_main"
    app:layout_dodgeInsetEdges="bottom" />   <-- Specifies this view dodges any views that inset the bottom edge

<android.support.design.widget.BottomNavigationView
    android:background="#fcfcfc"
    android:id="@+id/bottom_navigation"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom|end"
    app:menu="@menu/bottom_navigation"
    app:layout_insetEdge="bottom" />      <-- Specifies that this view insets the bottom edge

</android.support.design.widget.CoordinatorLayout>

11
这样做解决了底部重叠的问题,但却因AppBarLayout(即使使用了appbar_scrolling_view_behavior)导致顶部重叠。 - Desmond Lua
1
@DanieleSegato 不是这样的。将 app:layout_behavior="@string/hide_bottom_view_on_scroll_behavior" 添加到您的 BottomNavigationView 中,然后查看会发生什么 )) - Farid
这就是我一直在寻找的。另外,底部是FAB按钮的默认layout_dodgeInsetEdges布局,如果您想忽略它,则NONE无法使用,请将其设置为TOP或其他内容。 - zgr
1
应用时工具栏消失了。有什么想法吗? - kelalaka
对我很有用! 我在使用BottomAppBar时遇到了这个问题,这些设置解决了它。 你能否提供一个链接,让我知道你是从哪里获得这些信息的? - Matt Mc

2
你可以将RecyclerView和BottomNavigationView放在LinearLayout中,然后将LinearLayout放在CoordinatorLayout中。将RecyclerView的属性设置为layout_height="0dp"layout_weight="1",将BottomNavigationView的属性设置为layout_height="wrap_content"layout_gravity="bottom"
这是我的代码的一部分,希望对你有所帮助。
<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.v7.widget.Toolbar
            android:id="@+id/manager_main_toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

    </android.support.design.widget.AppBarLayout>

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <android.support.v4.widget.SwipeRefreshLayout
            android:id="@+id/swipe_refresh"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1">

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

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

        <android.support.design.widget.BottomNavigationView
            android:id="@+id/bottom_nav"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom"
            android:background="?android:attr/windowBackground" />

    </LinearLayout>

</android.support.design.widget.CoordinatorLayout>

如果将app:layout_scrollFlags="scroll|enterAlways"用于工具栏,则在向下滚动时会导致隐藏BottomNavigationView - Desmond Lua
这样做不允许在BottomNavigationView上使用Coordinator功能,例如将snackbar和floating action button移动到其上方。 - Carson Holzheimer

1
将回收视图或任何其他视图的高度设置为0dp,宽度设置为1。这将使其占据所有剩余的可用空间。

你能放上content_main布局吗? - nebuchadnezzar I
1
在include布局行中,将其设置为0dp并设置权重为1。如果这样不起作用,请尝试对frame布局/relative布局进行设置。 - nebuchadnezzar I

1
  1. 将您的BottomNavigationView移动到content_main.xml中,并将其放置在RelativeLayout内部
  2. BottomNavigationView添加属性android:layout_alignParentBottom="true"
  3. 为容器FrameLayout添加属性android:layout_above="@id/bottom_navigation"

请按照以下方式更新您的布局XML:

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.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"
    android:fitsSystemWindows="true"
    tools:context="com.bottombarnavigation.MainActivity">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">

      <include layout="@layout/toolbar"/>
    </android.support.design.widget.AppBarLayout>

    <include layout="@layout/content_main" />

</android.support.design.widget.CoordinatorLayout>

content_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
    android:background="@android:color/white"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="com.bottombarnavigation.MainActivity"
    tools:showIn="@layout/activity_main">

    <android.support.design.widget.BottomNavigationView
        android:id="@+id/bottom_navigation"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:background="#fcfcfc"
        app:menu="@menu/bottom_navigation" />

    <FrameLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@id/bottom_navigation" />
</RelativeLayout>

希望这能帮到您~

1
我有一个简单的解决方案,可能不是最好的,但它可以完成任务,只需创建一个高度与 appBar(工具栏)的高度相同的 View,使用 actionBarSize,appbar 和 bottomnav 的高度相同,因此您可以将您的 RecyclerView 约束到此视图的顶部,这样它就不会被您的 bottomnav 遮盖。
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
    tools:context=".ui.pedidos.PedidoFragment">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintBottom_toTopOf="@+id/view3"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <View
        android:id="@+id/view3"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

enter image description here


1
您可以向RecyclerView添加一个ItemDecorator来添加一些填充。我正在使用Kotlin而不是Java,但是一般的思路是:
 recyclerView.addItemDecoration(object : RecyclerView.ItemDecoration() {
        override fun getItemOffsets(outRect: Rect?, view: View?, parent: RecyclerView?, state: RecyclerView.State?) {
            // Get the position of the view in the recycler view
            val position = parent?.getChildAdapterPosition(view)
            if (position == null || position == RecyclerView.NO_POSITION) {
                return
            }

            if (position == parent.adapter.itemCount - 1) {
                // Add padding to the last item. You should probably use a @dimen resource.
                outRect?.bottom = 200
            }
        }
    })

不错的解决方案!如果可能的话,您能解释一下如何设置边距而不是填充吗? - marcolav

0

为BottomNavigationView设置一些静态高度(以dp为单位),而不是使用wrap_content,因为您的父布局即CoordinatorLayout扩展了FrameLayout,其默认行为是将其子视图放置在彼此上方。这就是为什么您的片段容器被BottomNavigationView覆盖的原因。


为片段容器指定静态高度。 - sohan shetty
请将您的协调布局替换为相对布局,并添加规则到其子视图以实现您的用户界面。 - sohan shetty

-1
在您的布局中包含的主要内容中,给予 RecyclerView 底部的边距。 因为 RecyclerView 被底部导航视图遮挡了。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接