Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to hide BottomNavigationView on android-navigation lib

Tags:

I am trying to use android-navigation lib in my APP and I do the things as the tutorial said. I just wanna use one single activity in my APP. I am confused about one question. some fragments that just don't want the BottomNavigationView, how can I hide it. here is my main_layout

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">

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

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:minHeight="?attr/actionBarSize"
            android:fitsSystemWindows="true"
            app:popupTheme="@style/AppTheme.PopupOverlay" >

        </androidx.appcompat.widget.Toolbar>

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

    <fragment
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        app:defaultNavHost="true"
        app:navGraph="@navigation/carkeeper_navigation"/>

<com.google.android.material.bottomnavigation.BottomNavigationView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/menu_bottom_nav"
    app:itemTextColor="@color/bottom_nav_title_color_selector"
    app:itemIconSize="@dimen/x40"
    app:menu="@menu/menu_main_bottom_nav"
    app:labelVisibilityMode="labeled">

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

here is my mainActivity

class MainActivity : BaseActivity() {

private lateinit var navController: NavController
private lateinit var bottomNavigationView: BottomNavigationView
private lateinit var appBarConfiguration: AppBarConfiguration

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.home_activity)

    navController = Navigation.findNavController(this, R.id.nav_host_fragment)
    appBarConfiguration = AppBarConfiguration(navController.graph, null)
    setSupportActionBar(findViewById(R.id.toolbar))

    bottomNavigationView = findViewById(R.id.menu_bottom_nav)
    bottomNavigationView.setupWithNavController(navController)
    bottomNavigationView.itemIconTintList = null
}}

then the navigaton_graph

<navigation 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:id="@+id/carkeeper_navigation"
app:startDestination="@id/mainFragment">

<fragment
    android:id="@+id/mainFragment"
    android:name="com.saicfinance.carkeeper.func.main.MainFragment"
    android:label="MainFragment"
    tools:layout="@layout/home_fragment">
</fragment>

<fragment
    android:id="@+id/mineFragment"
    android:name="com.saicfinance.carkeeper.func.mine.MineFragment"
    android:label="@string/mine_title"
    tools:layout="@layout/mine_fragment" >

    <action android:id="@+id/action_mine_fragment_to_setting_fragment"
        app:destination="@id/settingFragment"
        app:enterAnim="@anim/slide_in_right"
        app:exitAnim="@anim/slide_out_left"
        app:popEnterAnim="@anim/slide_in_left"
        app:popExitAnim="@anim/slide_out_right"/>
</fragment>

<fragment
    android:id="@+id/settingFragment"
    android:name="com.freddy.func.setting.SettingFragment"
    android:label="setting_fragment"
    tools:layout="@layout/setting_fragment" />

I know I can set BottomNavigationView gone when navigating to settingFragment. then set BottomNavigationView visible when back to mine fragment. But that is strange. anyone who can help me, thanks in advance.

like image 527
Freddy Avatar asked Jan 08 '19 08:01

Freddy


3 Answers

You could do something like this in your activity's onCreate. When ever an item in the nav bar is selected it will show or hide the nav based on the fragment id's.

private fun setupNav() {     val navController = findNavController(R.id.nav_host_fragment)     findViewById<BottomNavigationView>(R.id.bottomNav)         .setupWithNavController(navController)      navController.addOnDestinationChangedListener { _, destination, _ ->         when (destination.id) {             R.id.mainFragment -> showBottomNav()             R.id.mineFragment -> showBottomNav()             else -> hideBottomNav()         }     } }  private fun showBottomNav() {     bottomNav.visibility = View.VISIBLE      }  private fun hideBottomNav() {     bottomNav.visibility = View.GONE     } 
like image 63
Samuel Grogan Avatar answered Oct 23 '22 08:10

Samuel Grogan


There’s a solution to this on the official Android site:

https://developer.android.com/guide/navigation/navigation-ui

navController.addOnDestinationChangedListener { _, destination, _ ->    if(destination.id == R.id.full_screen_destination) {       toolbar.visibility = View.GONE       bottomNavigationView.visibility = View.GONE    } else {       toolbar.visibility = View.VISIBLE       bottomNavigationView.visibility = View.VISIBLE    } } 
like image 41
Tom Avatar answered Oct 23 '22 08:10

Tom


The accepted answer works, and it's the one recommended in the official documentation, but as stated on comments, it does cause some flickering, as the callback is executed before the fragment is attached.

I find the below answer more flexible, and handles animations better:

supportFragmentManager.registerFragmentLifecycleCallbacks(object : FragmentManager.FragmentLifecycleCallbacks() {
        override fun onFragmentViewCreated(fm: FragmentManager, f: Fragment, v: View, savedInstanceState: Bundle?) {
            TransitionManager.beginDelayedTransition(binding.root, Slide(Gravity.BOTTOM).excludeTarget(R.id.nav_host_fragment, true))
            when (f) {
                is ModalFragment -> {
                    binding.bottomNavigation.visibility = View.GONE
                }
                else -> {
                    binding.bottomNavigation.visibility = View.VISIBLE
                }
            }
        }
    }, true)

You can customize it depending on the transitions between your fragments, by choosing different animation (on my example it's a Slide), or by making the call at another lifecycle callback.

like image 26
Hicham Avatar answered Oct 23 '22 08:10

Hicham