There are chain MainFragment
> SettingsFragment
> SubSettingsFragment
:
MainFragment
to SettingsFragment
via NavigationControllernavController.navigate(MainFragment.toSettingsFragment())
Settings
to SubSettingsFragment
via PreferenceHeaderFragmentCompat<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<Preference
android:fragment=".SubSettingsFragment"
app:summary="@string/pref_header_summary_permission"
app:title="@string/pref_title_permission" />
</PreferenceScreen>
When we located at SubSettingsFragment
and press back button, appears MainFragment
. SettingsFragment
skipped.
PreferenceHeaderFragmentCompat
has onBackPressedCallback
handle accoding source code. But for some reason don't work.
Can we connect backstack of NavController
to PreferenceHeaderFragmentCompat
?
I found why onBackPressedCallback
don't work. In official source code in onViewCreated
, dispatcher from context is null. That's why addCallback
isn't run.
@CallSuper
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
onBackPressedCallback = InnerOnBackPressedCallback(this)
slidingPaneLayout.doOnLayout {
onBackPressedCallback!!.isEnabled =
slidingPaneLayout.isSlideable && slidingPaneLayout.isOpen
}
childFragmentManager.addOnBackStackChangedListener {
onBackPressedCallback!!.isEnabled = childFragmentManager.backStackEntryCount == 0
}
// this owner is null
val onBackPressedDispatcherOwner = requireContext() as? OnBackPressedDispatcherOwner
onBackPressedDispatcherOwner?.let {
it.onBackPressedDispatcher.addCallback(
viewLifecycleOwner,
onBackPressedCallback!!
)
}
}
I create custom PreferenceHeaderFragmentCompat
where change requireContext()
to requireActivity()
and it's works. Back pressed from SubSettingsFragment
pop to SettingsFragment
.
requireActivity().onBackPressedDispatcher.addCallback(
viewLifecycleOwner,
onBackPressedCallback!!
)
Do you know why requireContext() as? OnBackPressedDispatcherOwner
is null?
The problem was in onViewCreated()
of official PreferenceHeaderFragmentCompat
. Fixed by Google for future release (see issue).
// this owner is null when we use Hilt annotation - AndroidEntryPoint
val onBackPressedDispatcherOwner = requireContext() as? OnBackPressedDispatcherOwner
onBackPressedDispatcherOwner?.let {
it.onBackPressedDispatcher.addCallback(
viewLifecycleOwner,
onBackPressedCallback!!
)
}