StayCool
StayCool

Reputation: 449

Hiding toolbar or bottomNavigationBar in Navigation Component

I followed guide from android.developers and implemented a navigation component into my app. I stumbled across a problem when I need some screens to be with or without a toolbar/bottom navbar.

Android developers example's layout

  <androidx.appcompat.widget.Toolbar
        .../>

    <fragment
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"

        app:defaultNavHost="true"
        app:navGraph="@navigation/nav_graph" />

    <com.google.android.material.bottomnavigation.BottomNavigationView
        .../>

forces me to hide/show toolbar/bottomNavBar in OnDestinationChanged callback in MainActivity:

navController.addOnDestinationChangedListener { _, destination, _ ->
                when (destination) {
                    R.id.topLevelDestination-> {
                        toolbar.visibility = View.GONE
                        bottomNav.visibility = View.VISIBLE
                    }
                    R.id.lowLevelDestination -> {
                        toolbar.visibility = View.VISIBLE
                        bottomNav.visibility = View.GONE
                    }

And, of course, if I do it like this I have my layout resize before I see new fragment. I mean I see how bottom nav disappears on fragment A, and I see fragment's B parts in the place where bottomNavBar was when fragment A is still on the screen, and after that fragment, B appears.

How to solve it? Do I need nested nav graphs?


update: Added a gif of problem

enter image description here

Video description: it's a cutted part of my screen. On video you can see system UI, bottom nav bar and main fragment with a button. When i click button nav graph navigates me to a destination without bottom navigation bar. So, I do bottomNavBar.hide() when OnDestinationChanged. As you can see, bottomNavBar is disappeared BEFORE I actually navigate and you can see part of my destination fragment visible after bottomnavBar gone. That's the problem.

Upvotes: 17

Views: 4958

Answers (1)

luisenricke
luisenricke

Reputation: 169

I stuck in this like 2 days but with XML you can solve your problem

  1. You need to wrap your toolbar into CoordinatorLayout
  2. Your toolbar needs scrollFlags: scroll and enter
  3. You need to wrap your fragment in other layour and put in layout_behavior the specific behavior: @string/appbar_scrolling_view_behavior
  4. In your BottomNavigationView put google behavior: com.google.android.material.behavior.HideBottomViewOnScrollBehavior

Something like that:

<androidx.coordinatorlayout.widget.CoordinatorLayout
    ...>

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/appBar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:layout_scrollFlags="scroll|enterAlways"
            app:popupTheme="@style/ThemeOverlay.AppCompat.ActionBar" />

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

    <androidx.core.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <fragment
            android:id="@+id/fragment_host"
            android:name="androidx.navigation.fragment.NavHostFragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:defaultNavHost="true"
            app:navGraph="@navigation/graph_main" />
    </androidx.core.widget.NestedScrollView>

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottom"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_gravity="bottom"
        android:layout_marginStart="0dp"
        android:layout_marginEnd="0dp"
        android:background="?android:attr/windowBackground"
        app:labelVisibilityMode="unlabeled"
        app:layout_behavior="com.google.android.material.behavior.HideBottomViewOnScrollBehavior"
        app:menu="@menu/menu_main" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

By the way, I put the NestedScrollView to make all my fragments ready to scroll and save me other layout where I need it

Upvotes: 4

Related Questions