Recyclerview covered by BottomNavigationView in CoordinatorLayout

15k views Asked by At

I tried Google Support Library BottomNavigationView with a Framelayout for my Fragments .

Here are my code

<?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>

When i populate my Recyclerview inside the Fragment, it's content got covered up by the BottomNavigationView .

enter image description here

I have no idea why this happens. I look through other people tutorial and it works fine.

EDIT Here is my content_main.xml file

<?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>
9

There are 9 answers

1
chet On BEST ANSWER

Here my solution, is working for me.

I have almost the same layout as you, I moved the BottomNavigationView out of the CoordinatorLayout as I don't need any animation on it. I've aligned BottomNavigationView to the parent's bottom, and added layout_above to CoordinatorLayout to have it above the BottomNavigationView but filling all the screen.

With this configuration I fixed the overlapping issue, I hope this would help you.

Here you have my layout.

    <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
sohan shetty On

Give some static height in dp for BottomNavigationView instead of wrap_content because your parent layout i,e coordinator layout extends framelayout which its default behavior is placing its child views one above the other. Thats y your fragment container is covered up by botomnavigationview.

2
nebuchadnezzar I On

Set the recycle veiw or whatever view its in, height to 0dp and weight 1. This will make it take all the available space left.

0
Gastón Saillén On

I have a simple solution, may not be the best, but it does the job, just create a View with height as the height of an appBar (toolbar) with actionBarSize , the height of the appbar and the bottomnav are the same, so you can constrain your recyclerview to the top of this view, doing this it will not be covered by your 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

2
SUI On

You can put the RecyclerView and the BottomNavigationView in a LinearLayout, and then put the LinearLayout in the CoordinatorLayout. Set the attribute of RecyclerView as layout_height="0dp" layout_weight="1", and the attribute of the BottomnavigationView as layout_height="wrap_content" layout_gravity="bottom".

Here is part of my code, wish to help you.

<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>
0
Gaurav sappal On

In the main content that you are included into your layout. Give the margin bottom to the recycler view. Because recycler view is hide behind the bottom navigation view

0
Ferdous Ahamed On
  1. Move your BottomNavigationView to content_main.xml and place it inside RelativeLayout
  2. Add attribute android:layout_alignParentBottom="true" to BottomNavigationView
  3. Add attribute android:layout_above="@id/bottom_navigation" to container FrameLayout

Update your layout XML's as below:

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>

Hope this will help~

1
reacuna On

You can add an ItemDecorator to your recycler view that adds some padding. I'm using Kotlin instead of Java, but the general idea is:

 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
            }
        }
    })
5
Sound Conception On

One of the most useful feature of CoordinatorLayout is view dodging.

Child views of the CoordinatorLayout can be assigned as "insetting" an edge. Any other child view that you assign as dodging that same edge will then be adjusted to suit.

In your case you would do something like the following:

<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>