是否可以使用 Android Jetpack 导航组件来导航设置首选项的片段?我有一个带有多个嵌套首选项片段的设置屏幕。我想知道使用 Android Jetpack 导航组件来完成我的任务是否可行?
2 回答
谷歌文档指出,偏好的分层嵌套现在已被弃用,有利于片段间导航;那就是现在的结构<PreferencesScreen> ... <PreferencesScreen ...> ... </PreferenceScreen> ... </PreferenceScreen>
。
文件建议<PreferenceScreen/>
用首选项替换嵌套并设置app:fragment
属性,因此
<xml ...>
<PreferencesScreen ...>
<Preference
android:title="Title"
app:fragment="TLD.DOMAIN.PACKAGE.preferences.SUBPreferenceFragment"
app:destination="@+id/SUBPreferenceFragment" # Not supported by Schema
android:summary="Summary"/>
</PreferenceScreen>
注意: 如果他们允许app:destination="@+id/SUBPreferenceFragment"
识别导航目的地,那将非常方便;app:destination
我只是从导航图的 XML 文件中复制。
从文档中,可以PREFERENCEFramgent
通过引用 this 在 s之间导航preference.fragment
,如下所示
class Activity : AppCompatActivity(),
// Preferences Interface
PreferenceFragmentCompat.OnPreferenceStartFragmentCallback
{
...
override fun onPreferenceStartFragment(caller: PreferenceFragmentCompat, preference: Preference): Boolean
{
// Instantiate the new Fragment
val args = preference.extras
val fragment = supportFragmentManager.fragmentFactory.instantiate(
classLoader,
preference.fragment)
fragment.arguments = args
fragment.setTargetFragment(caller, 0)
// Replace the existing Fragment with the new Fragment
supportFragmentManager.beginTransaction()
.replace(R.id.FRAGMENT, fragment)
.addToBackStack(null)
.commit()
return true
}
...
}
然而,有一个小的 Snafoo !R.id.FRAGMENT
在正常活动中表示活动视图中的占位符,在该占位符中,人们将交换不存在的主要片段。当使用 Navigation R.id.FRAGMENT
maps to时R.id.NAVIGATION
,上面的代码用首选项交换了整个导航片段。对于使用导航的活动,需要重新制定。
class Activity : AppCompatActivity(),
// Preferences Interface
PreferenceFragmentCompat.OnPreferenceStartFragmentCallback
{
...
override fun onPreferenceStartFragment(caller: PreferenceFragmentCompat, preference: Preference): Boolean {
// Retrieve the navigation controller
val navctrl = findNavController(R.id.navigation)
// Identify the Navigation Destination
val navDestination = navctrl.graph.find { target -> preference.fragment.endsWith(target.label?:"") }
// Navigate to the desired destination
navDestination?.let { target -> navctrl.navigate(target.id) }
}
...
}
虽然这可行,但我对决定navDestination
. 如果您有更好的咒语,val navDestination = navctrl.graph.find { target -> preference.fragment.endsWith(target.label?:"") }
请编辑问题或相应地发表评论,以便我更新答案。
是的,您可以在 Preference 片段中使用 Navigation 组件。
我还有一个包含多个嵌套片段的主要偏好片段。对我来说,最好的方法是在没有任何活动的情况下仅在偏好片段内部导航。所以我创建了 onPreferenceClickListeners 并像从普通片段中一样导航。
findPreference(getString(R.string.PREF_GN_BUTTON_MAIN)).setOnPreferenceClickListener(preference5 -> {
Navigation.findNavController(requireView()).navigate(R.id.another_settings_fragment);
return true;
});
这种方式的好处是你可以使用 gradle 插件Safe args在目的地之间导航。因此,它比仅使用 id 更安全一些,就像Activity 中的Carel一样。
我试图覆盖onPreferenceStartFragment
我的活动,但我看不到它的任何优势。我使用单活动架构。