Android Navigation Component not saving fragment state with BottomNavigationView - android

I'm using Navigation fragment version 2.5.0. As release of version 2.4.0-alpha01, it's suppose to support back stack support for bottom navigation without writing any additional code. But my fragments are re-created everytime while I navigate with bottom navigation.
I'm using single graph, single activity Architecture.
Navigation dependencies
implementation 'androidx.navigation:navigation-fragment-ktx:2.5.0'
implementation 'androidx.navigation:navigation-ui-ktx:2.5.0'
Nav-controller
val navHostFragment = supportFragmentManager.findFragmentById(
R.id.nav_host_container
) as NavHostFragment
navController = navHostFragment.navController
// Setup the bottom navigation view with navController
val bottomNavigationView = findViewById<BottomNavigationView>(R.id.bottom_nav)
bottomNavigationView.setupWithNavController(navController)
// Setup the ActionBar with navController and 3 top level destinations
appBarConfiguration = AppBarConfiguration(
setOf(R.id.titleScreen, R.id.leaderboard, R.id.register)
)
setupActionBarWithNavController(navController, appBarConfiguration)

Related

Navigation in Bottom Navigaiton View creates/destroys the fragment Navigation 2.4.2

I am using the latest Navigation version 2.4.2.
I set up the bottom nav bar with the Navigation component as follow, the same way recommended by google:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
val navView: BottomNavigationView = binding.navView
val navController = findNavController(R.id.nav_host_fragment_activity_main)
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
val appBarConfiguration = AppBarConfiguration(
setOf(
R.id.navigation_home, R.id.navigation_dashboard, R.id.navigation_notifications
)
)
setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController)
}
My menu:
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/navigation_home"
android:icon="#drawable/ic_home_black_24dp"
android:title="#string/title_home" />
<item
android:id="#+id/navigation_dashboard"
android:icon="#drawable/ic_dashboard_black_24dp"
android:title="#string/title_dashboard"
xmlns:app="http://schemas.android.com/apk/res-auto" />
<item
android:id="#+id/navigation_notifications"
android:icon="#drawable/ic_notifications_black_24dp"
android:title="#string/title_notifications" />
However, when I navigate from one fragment to the other, its onDestroy() is called and when I navigate back to it is recreated.
This is the case for all the fragment in the BottomNavView except the startDestination. The onCreate() for the startDestination is called only once and when navigating away from it, only the onDestroyView() is called. I want this behavior for all the other fragments as well as I need to put code in the onCreate() method and want it to run once once per lifecycle of the app.
Support for multiple backstack arrive with Navigation 2.4.0 so I don't know what's wrong. when calling findNavController.navigate(...), the previous fragment is kept in the backstack and is not destroyed(), and as far as I know the BottomNavBar calls the same method so I can't figure out why each fragment is being created/destroyed upon each navigation.
Me navigating from : Start Fragment -> Dashboard Fragment -> Navigation Fragment -> Start Fragment
All the fragment except the Start Fragment is recreated.
Any help is appreciated.
For anyone looking for an answer to this question. Google replied that it is expected behaviour.
https://issuetracker.google.com/issues/190893266

How can I show a fragment using a BottomNavigationView with valid back stack?

Edit:
The original question was Is there a way to get a reference to a fragment that is displayed using a BottomNavigationView?. But I've figured some things out and realized I was asking the wrong question.
I'd like to get a reference to a fragment that is being displayed using a BottomNavigationView.
This is how my BottomNavigationView is being setup. It's in onCreate of an Activity.
val navView: BottomNavigationView = findViewById(R.id.nav_view)
val navController = findNavController(R.id.bottom_nav_view_nav_host)
val appBarConfiguration = AppBarConfiguration(setOf(
R.id.navigation_first_list,
R.id.navigation_second
))
setupActionBarWithNavController(navController, appBarConfiguration)
bottomNav.setupWithNavController(navController)
I've tried to get the fragment with bottomNav.findFragment<TheFragmentType>() it throws an exception.
I was asking the wrong question originally. I can just use the navController to call the correct navigation component in order to show the right fragment with a back stack.
val bundle = bundleOf("someId" to "theId")
navController.navigate(R.id.action_navigation_list_to_details, bundle)

why is Navigation Component fragment Label not working

hello i am changing the label of fragment in navigation file but the fragment title in the tool bar isn't changing, any solution?
<fragment
android:id="#+id/navHostFragment"
android:name="com.example.androidtask.view.UsersList"
android:label="#string/user_list"
tools:layout="#layout/fragment_users_list">
<action
android:id="#+id/submit_user"
app:destination="#id/addUser" />
</fragment>
you need to setup ActionBar to work with navigation , add this code in activity onCreate()
val navController = findNavController(R.id.nav_host_fragment)// where nav_host_fragment is the id for your Main NavHost fragment
val appBarConfiguration = AppBarConfiguration(navController.graph)
setupActionBarWithNavController(navController, appBarConfiguration)
for more info check this

Remove all Navigation Backstacks

I'm using new jetpack navigation library. Here I have 3 fragments A, B & C. A is my main fragment. From A fragment navigate to B fragment(A->B). From B to C(B->C). C->A then A->C->B->A->B like this. From whichever fragment I navigate if I press the system back button then I should navigate to A fragment Without having any backstacks pending.
Place fragment A as a start destination and then add them all as top level destinations. For that you would need an AppBarConfiguration:
private lateinit var appBarConfiguration: AppBarConfiguration
//in onCreate or somewhere
appBarConfiguration = AppBarConfiguration(
setOf(
R.id.fragmentA,
R.id.fragmentB,
R.id.fragmentC
)
)
setupActionBarWithNavController(navController, appBarConfiguration)

How to Set BottomNavigationView in AndroidX with No ActionBar

I am using Android architecture components with the Single Activity pattern on Android. The navigation pattern I am using is BottomNavigationView.I actually want the parent activity to have no ActionBar but setting my theme to be of type NoActionBar crashes the App. Setting Navigation in Activity has been done as below
val navController = findNavController(R.id.nav_host_fragment)
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
val appBarConfiguration = AppBarConfiguration(
setOf(R.id.navigation_popular, R.id.navigation_top_rated, R.id.navigation_favorites)
)
setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController)
How do I set up bottom navigation to have no actionBar since I wish to have on of the some fragments with ActionBar, like CollapsingToolbarLayout?
I think you found the solution but for the others,
if you want to use the BottomNavigationView with the .NoActionBar theme so you should remove these lines:
val appBarConfiguration = AppBarConfiguration(
setOf(R.id.navigation_popular, R.id.navigation_top_rated, R.id.navigation_favorites)
)
setupActionBarWithNavController(navController, appBarConfiguration)
Using Android Navigation BottomNavigationView. Do not restrict activity with NoActionBar in manifest. Instead from your activity retrieve an instance of your support action bar and use its public method hide()
if (savedInstanceState == null) {
setupBottomNavigationBar()
} // Else, need to wait for onRestoreInstanceState
supportActionBar?.hide()

Categories

Resources