Reputation: 345
So I have:
Fragment A: here there is a viewPager2 and TabLayout with 2 tabs, Fragment B and C.
Then inside Fragment B , I have a button that goes to a Fragment D outside of the TabLayout
, there I want get some data, go back and populate a TextView
on Fragment B in the TabLayout
in Fragment A.
It works fine until I am on Fragment D and try to get back to Fragment B and get Fragment no longer exists for key f#0
How can I fix this?
Fragment A TabLayout
Adapter:
private inner class ScreenSlidePagerAdapter(fa: FragmentActivity) : FragmentStateAdapter(fa) {
override fun getItemCount(): Int = 2
override fun createFragment(position: Int): Fragment {
return if (position == 0) FragmentB()
else FragmentC()
}
}
Fragment B:
findNavController().currentBackStackEntry?.savedStateHandle?.getLiveData<String>("key")?.observe(
viewLifecycleOwner) { result ->
binding.textView.text = result
}
Fragment D:
fun onGoBack(data: String){
findNavController().apply {
previousBackStackEntry?.savedStateHandle?.set("key", data)
navigateUp()
}
}
MainActivity onSupportNavigateUp
:
override fun onSupportNavigateUp(): Boolean {
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
}
NavGraph:
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/navigation"
app:startDestination="@id/fragmentA">
<fragment
android:id="@+id/fragmentA"
android:name="com.example.FragmentA"
android:label="Fragment A" />
<fragment
android:id="@+id/fragmentB"
android:name="com.example.FragmentB"
android:label="FragmentB" />
<fragment
android:id="@+id/fragmentC"
android:name="com.example.FragmentC"
android:label="FragmentC" />
<fragment
android:id="@+id/fragmentD"
android:name="com.example.FragmentD"
android:label="FragmentD" />
</navigation>
Upvotes: 0
Views: 1147
Reputation: 40840
You shouldn't add ViewPager
page fragments into the NavGraph
not only it can introduce memory leaks but also it can introduce IllegalStateException
for the navGraph
.. Check here for more details.
But what you can do instead to solve this:
Remove the pager B & C fragments from the navigation graph. So the navGraph
now contains A & D
Since Fragment B is not a part of the navGraph
, Make the navigation that you need from the Fragment B to D through Fragment A:
In Fragment B:
val fragmentA: FragmentA = requireParentFragment() as FragmentA
fragmentA.openFragmentD()
In Fragment A:
fun openFragmentD() {
val navHostFragment: NavHostFragment = ...;
val navController: NavController = navHostFragment.getNavController()
navController.navigate(FragmentADirections.actionFragmentAToFragmentD())
}
Likewise: As you need to return some data from D back to B
Then receive this data through Fragment A onCreateView()
val data = FragmentAArgs.fromBundle(getArguments())
Now it's easy to either update the ViewPager
fragment B with the new data, or you can share it in a shared ViewModel
between the fragments.
Upvotes: 1