23

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>
Zain
  • 37,492
  • 7
  • 60
  • 84
EggRollMan
  • 583
  • 1
  • 8
  • 20

9 Answers9

27

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>
chet
  • 286
  • 2
  • 2
  • 2
    Wasted so much time to fix this issue, finally such a simple trick fixes the problem. Thanks for sharing... – Rinav Dec 03 '18 at 11:19
6

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>
Sound Conception
  • 5,263
  • 5
  • 30
  • 47
  • 11
    This solve the bottom overlap issue but causes top overlap by AppBarLayout (even though appbar_scrolling_view_behavior is used) – Desmond Lua May 06 '18 at 12:56
  • 1
    @DanieleSegato it's not. Add `app:layout_behavior="@string/hide_bottom_view_on_scroll_behavior"` to your `BottomNavigationView` and check what happens )) – Farid Aug 09 '19 at 16:42
  • This is the one I was looking for. Additionally: Bottom is the default layout_dodgeInsetEdges of FAB button, if you want to ignore it NONE doesn't work, so make it TOP or something else. – zgr Aug 29 '19 at 07:07
  • 1
    Toolbar is missing when applied. Any idea? – kelalaka Apr 23 '20 at 12:36
  • Worked for me! Had this issue with a BottomAppBar and those settings solved it beautifully. Would you care to link to the source for how you knew to do this? – Matt Mc May 14 '20 at 04:21
2

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>
Axel
  • 3,331
  • 11
  • 35
  • 58
SUI
  • 21
  • 2
  • If `app:layout_scrollFlags="scroll|enterAlways"` is used for toolbar, it will cause `BottomNavigationView` to be hidden when scroll down. – Desmond Lua May 06 '18 at 13:03
  • This doesn't allow Coordinator functions to be used on BottomNavigationView, like moving snackbars and floating actions buttons above it – Carson Holzheimer Oct 01 '19 at 05:29
1

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.

nebuchadnezzar I
  • 125
  • 1
  • 12
1
  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~

Ferdous Ahamed
  • 21,438
  • 5
  • 52
  • 61
1

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
            }
        }
    })
reacuna
  • 463
  • 9
  • 17
1

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

Gastón Saillén
  • 12,319
  • 5
  • 67
  • 77
0

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.

sohan shetty
  • 289
  • 1
  • 16
-1

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

Gaurav sappal
  • 81
  • 1
  • 5