Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 809
StayCool Avatar asked Jun 18 '20 11:06

StayCool


People also ask

How do I hide the navigation bar?

Way 1: Touch “Settings” -> “Display” -> “Navigation bar” -> “Buttons” -> “Button layout”. Choose the pattern in “Hide navigation bar” -> When the app opens, the navigation bar will be automatically hidden and you can swipe up from the bottom corner of the screen to show it.

How do I hide the bottom navigation bar in a fragment?

To do this, use SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION . You may also need to use SYSTEM_UI_FLAG_LAYOUT_STABLE to help your app maintain a stable layout.


1 Answers

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

like image 127
luisenricke Avatar answered Oct 17 '22 12:10

luisenricke