英文:
Bug of OnBackPressedDispatcher in androidx preference
问题
以下是您提供的内容的翻译:
有一个导航链 MainFragment
> SettingsFragment
> SubSettingsFragment
:
- 从
MainFragment
到SettingsFragment
通过 NavigationController
navController.navigate(MainFragment.toSettingsFragment())
- 从
Settings
到SubSettingsFragment
通过 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>
当我们位于 SubSettingsFragment
并按下返回按钮时,出现 MainFragment
。SettingsFragment
被跳过。
PreferenceHeaderFragmentCompat
有一个根据 源代码 处理的 onBackPressedCallback
。但由于某种原因它不起作用。
我们能将 NavController
的返回栈连接到 PreferenceHeaderFragmentCompat
吗?
更新 1
我找到了为什么 onBackPressedCallback
不起作用的原因。在官方源代码中,在 onViewCreated
中,来自上下文的调度程序为空。这就是为什么 addCallback
没有运行的原因。
@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!!
)
}
}
我创建了一个自定义的 PreferenceHeaderFragmentCompat
,将 requireContext()
更改为 requireActivity()
,它可以正常工作。从 SubSettingsFragment
返回按下返回按钮将弹出到 SettingsFragment
。
requireActivity().onBackPressedDispatcher.addCallback(
viewLifecycleOwner,
onBackPressedCallback!!
)
您知道为什么 requireContext() as? OnBackPressedDispatcherOwner
为空吗?
英文:
There are chain MainFragment
> SettingsFragment
> SubSettingsFragment
:
- from
MainFragment
toSettingsFragment
via NavigationController
navController.navigate(MainFragment.toSettingsFragment())
- from
Settings
toSubSettingsFragment
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
?
Update 1
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?
答案1
得分: 0
问题出在官方的PreferenceHeaderFragmentCompat
的onViewCreated()
方法中。Google已经修复了这个问题,将在未来的发布版本中发布(请参见问题)。
// 当我们使用Hilt注解时,此所有者为空 - AndroidEntryPoint
val onBackPressedDispatcherOwner = requireContext() as? OnBackPressedDispatcherOwner
onBackPressedDispatcherOwner?.let {
it.onBackPressedDispatcher.addCallback(
viewLifecycleOwner,
onBackPressedCallback!!
)
}
英文:
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!!
)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论