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.
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 }
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 } }
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With