I'm trying to create a single activity Android application. I have MainActivity (only activity) with BottomNavigationView, three top level fragments and some child fragments. My requirement is whenever the screen is showing top level fragments, bottom navigation should be visible such that switching is possible. But when I'm viewing any of the child fragments, bottom navigation should be hidden. Is there any out-of-box way using the Navigation component or need to change the visibility manually ?
6 Answers
Update (Navigation component 1.0)
As of Navigation component 1.0.0-alpha08, method addOnNavigatedListener(controller: NavController, destination: NavDestination)
was changed to addOnDestinationChangedListener(controller: NavController, destination: NavDestination, arguments: Bundle)
. Its behavior was also slightly changed (it is also called if the destinations arguments change).
Old Answer
You can use NavController.OnNavigatedListener to achieve this behavior (set it in Activity onCreate):
findNavController(R.id.container).addOnNavigatedListener { _, destination ->
when (destination.id) {
R.id.dashboardFragment -> showBottomNavigation()
else -> hideBottomNavigation()
}
}
private fun hideBottomNavigation() {
// bottom_navigation is BottomNavigationView
with(bottom_navigation) {
if (visibility == View.VISIBLE && alpha == 1f) {
animate()
.alpha(0f)
.withEndAction { visibility = View.GONE }
.duration = EXIT_DURATION
}
}
}
private fun showBottomNavigation() {
// bottom_navigation is BottomNavigationView
with(bottom_navigation) {
visibility = View.VISIBLE
animate()
.alpha(1f)
.duration = ENTER_DURATION
}
}

- 1,506
- 14
- 16
-
1Is using `addOnNavigatedListener` still possible? I get an unresolved reference when trying to use it? – IainCunningham Mar 03 '19 at 14:00
-
2`addOnNavigatedListener` is changed to `addOnDestinationChangedListener` – Kalyan Dechiraju Mar 18 '19 at 18:18
-
Where is `EXIT_DURATION` and `ENTER_DURATION` defined? – A1m Mar 26 '20 at 08:02
-
@A1m you can define them wherever you want, these are just constants in milliseconds. – theme_an Mar 26 '20 at 20:03
-
But how can I get them matching, such that the BottomNavigation does always align with the Fragments. Without this sometimes you can see a delay where the Fragment appears but the Bar appears later or the other way around. – A1m Mar 27 '20 at 02:02
-
1@A1m yeah, this solution does has such problem, but it was written before FragmentLifecycleCallbacks was there. I recommend you trying out Hicham's solution for better animation choreographing. – theme_an Mar 27 '20 at 06:02
Using addOnDestinationChangedListener works, and it's the solution recommended in the official documentation, but 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.

- 720
- 6
- 9
-
-
This doesn't depend on the navigation component, it depends only on the fragment manager. – Hicham Sep 21 '20 at 14:58
-
I've already solved my problem. I change the visibility in my onCreateView and change the visibility again in my main Fragment. This works better than your approach, without any flicker etc. – Andrew Sep 21 '20 at 15:44
-
1
You have to make a method in MainActivity for visibility. Do call that method from fragments where you want to show or hide.
One thing I faced with such scenario is, bottom navigation visibility is not being properly gone. So I put bottom navigation view in Relative layout and hide that parent view.

- 19,824
- 17
- 99
- 186

- 2,731
- 1
- 14
- 22
you just need to write this code in MainActivity
class MainActivity : AppCompatActivity() {
private lateinit var navController: NavController
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//Getting the Navigation Controller
navController = Navigation.findNavController(this, R.id.fragment)
//Setting the navigation controller to Bottom Nav
bottomNav.setupWithNavController(navController)
//Setting up the action bar
NavigationUI.setupActionBarWithNavController(this, navController)
//setting the Bottom navigation visibiliy
navController.addOnDestinationChangedListener { _, destination, _ ->
if(destination.id == R.id.full_screen_destination ){
bottomNav.visibility = View.GONE
}else{
bottomNav.visibility = View.VISIBLE
}
}
}
get more details from the android developer documentation: Update UI components with NavigationUI

- 220
- 2
- 9
So even tho this question was already answered and the accepted answer is one that works, here is the code to actually achieve this behaviour:
MainActivity
fun hideBottomNav() {
bottomNavigationView.visibility = View.GONE
}
fun showBottomNav() {
bottomNavigationView.visibility = View.VISIBLE
}
Then you call the functions in your fragment onViewCreated()
, onDetach()
function, like:
Fragment
class FragmentWithOutBottomNav() : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
(activity as MainActivity).hideBottomNav()
}
override fun onDetach() {
super.onDetach()
(activity as MainActivity).showBottomNav()
}
}
Hope I could help some people. Happy coding!

- 4,264
- 1
- 21
- 65
navController.addOnDestinationChangedListener { _, destination, _ ->
val isMainPage = bottomNavigationView.selectedItemId == destination.id
bottomNavigationView.isVisible = isMainPage
}

- 371
- 3
- 4