2

I'm having difficulties getting AppBarLayout, NestedScrollView and BottomNavigationView working together properly. My problem is that when I set app:layout_behavior="@string/appbar_scrolling_view_behavior" on the NestedScrollView, it extends behind the BottomNavigationView as illustrated here. View in layout editor

View in app

So the issue is that the BottomNavBar overlays the content, instead of the content stopping at the top of the Nav.

I've tried many solutions, including wrapping the layout in a RelativeLayout and putting the BottomNavView in that instead of the CoordinatorLayout.

Here's the basic layout from the sample project I've attached.

<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"
    tools:context="com.example.android.navigationadvancedsample.MainActivity">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/app_bar_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:elevation="0dp">

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_scrollFlags="scroll|enterAlways" />
    </com.google.android.material.appbar.AppBarLayout>

    <androidx.core.widget.NestedScrollView
        android:id="@+id/app_scroll_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        android:fillViewport="true">
        <FrameLayout
            android:id="@+id/nav_host_container"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1" />
    </androidx.core.widget.NestedScrollView>

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottom_nav"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        app:menu="@menu/bottom_nav"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

Here's a small sample project that reproduces the issue (based on the Navigation components sample from Google). Can someone please tell me what I'm doing wrong?

aaronmarino
  • 3,723
  • 1
  • 23
  • 36
  • You can apply a layout behavior to the bottom navigation to hide it on scroll. Check here: https://stackoverflow.com/questions/44777869/hide-show-bottomnavigationview-on-scroll – Bilal Naeem Jul 09 '19 at 18:01
  • @BilalNaeem Unfortunately the requirement from the client is that the BottomNav must always be visible. – aaronmarino Jul 09 '19 at 18:07
  • Well then the easiest solution would be to give a bottom padding to your NestedScrollView equal to the height of your BottomNavigation. – Bilal Naeem Jul 09 '19 at 18:08
  • If you wrap everything in a LinearLayout and put the BottomNav at the bottom and it will work. I currently am working on an app with this layout. – Hayes Roach Jul 09 '19 at 18:10
  • @BilalNaeem That seems like a hack and I'm convinced there must be a better solution. Also, when I do this I can scroll content past the nav bar. It should stop at the top of the nav bar. – aaronmarino Jul 09 '19 at 18:17
  • @HayesRoach when I try this the NavBar is off the bottom of the screen, invisible. – aaronmarino Jul 09 '19 at 18:18
  • @aaronmarino This is because your ScrollView is taking up all of the space. Try changing the height/weight of it – Hayes Roach Jul 09 '19 at 18:21
  • Did you solve it? – kelalaka Jan 17 '20 at 16:34

3 Answers3

1

You just have to take BottomNavigationView out of the CoordinatorLayout and put both inside a RelativeLayout.

I was facing same problem and found the solution here. Hope it helps.

leo_corder
  • 11
  • 4
0

In your code, your NestedScrollView was taking up the whole screen. Using a vertical LinearLayout with weights you can make it to where the NestedScrollView stops at the top of the NavBar like you want.

<androidx.core.widget.NestedScrollView
    android:id="@+id/app_scroll_view"
    android:layout_width="match_parent"
    android:layout_height="0dp" *** changed from match_parent to 0dp
    android:layout_weight="1" *** added weight to fill remaining screen
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    android:fillViewport="true">
    <FrameLayout
        android:id="@+id/nav_host_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/> *** changed from 0dp to match_parent
</androidx.core.widget.NestedScrollView>

The way it now is set up takes into account the NavBar and expands the layout of the NestedScrollView to fill the remaining empty space on the screen. Now the NestedScrollView will not expand beyond the NavBar.

Hayes Roach
  • 121
  • 10
  • Can you post the xml for the whole screen? I'm struggling to understand where the LinearLayout goes. Do you mean wrap the CoordinatorLayout (in which case the about layout weight changes wont work) or wrap the NestedScrollView (in which case the scroll layout_behaviour will no longer work)? – aaronmarino Jul 10 '19 at 08:40
0

Not sure . But seem like working in preview . Putting nestedScrollView and BottomNavigation view inside a relative layout .

 <RelativeLayout android:layout_width="match_parent" 
android:layout_height="match_parent">


<androidx.core.widget.NestedScrollView
        android:id="@+id/app_scroll_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@+id/bottom_nav"
        android:fillViewport="true" android:layout_marginBottom="-2dp">
    <FrameLayout
            android:id="@+id/nav_host_container"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"/>
</androidx.core.widget.NestedScrollView>

<com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottom_nav"
        android:layout_alignParentBottom="true"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        app:menu="@menu/bottom_nav_menu"/>
</RelativeLayout>
Mini Chip
  • 949
  • 10
  • 12
  • 1
    Thanks for the suggestion, but this breaks the scrolling behaviour. If I try to put the layout_behaviour on the relative layout, then the bottomNav scrolls with the content instead of remaining stuck to the bottom. – aaronmarino Jul 10 '19 at 08:30