Currently, I am playing around Android Navigation Component with Bottom Navigation Bar. While playing I realized two facts:
- Fragments are always recreated (
onCreate
,onViewCreated
,onViewDestroyed
are called as soon as the user navigates to another fragment) savedInstanceState
is always null (inonCreate
,onViewCreated
, etc.)
The first issue can be fixed by using custom FragmentNavigator
, which will reuse fragment if it already exists
package am.chamich.apps.advancedbottomnavigation.navigator
import android.content.Context
import android.os.Bundle
import androidx.navigation.NavDestination
import androidx.navigation.NavOptions
import androidx.navigation.Navigator
import androidx.navigation.fragment.FragmentNavigator
@Navigator.Name("retain_state_fragment")
class RetainStateFragmentNavigator(
private val context: Context,
private val manager: androidx.fragment.app.FragmentManager,
private val containerId: Int
) : FragmentNavigator(context, manager, containerId) {
override fun navigate(
destination: Destination,
args: Bundle?,
navOptions: NavOptions?,
navigatorExtras: Navigator.Extras?
): NavDestination? {
val tag = destination.id.toString()
val transaction = manager.beginTransaction()
val currentFragment = manager.primaryNavigationFragment
if (currentFragment != null) {
transaction.detach(currentFragment)
}
var fragment = manager.findFragmentByTag(tag)
if (fragment == null) {
val className = destination.className
fragment = instantiateFragment(context, manager, className, args)
transaction.add(containerId, fragment, tag)
} else {
transaction.attach(fragment)
}
transaction.setPrimaryNavigationFragment(fragment)
transaction.setReorderingAllowed(true)
transaction.commit()
return destination
}
}
Question
For the second issue, I have no idea how to fix it, actually, I even didn't understand how the fragment is restoring its state (for example when you rotate the screen), I tied to use fragment.setInitialSavedState(savedState)
to save and restore fragment state, but that doesn't help in this situation.
Actually what I need to know is when fragment view was recreated
Here is a link to my GitHub project, any help is welcome.
saveinstance
state is always null :( – Consent