是否可能使用Android Jetpack Navigation组件导航到设置偏好的片段?我有一个带有多个嵌套Preference片段的设置屏幕。我想知道是否可以使用Android Jetpack Navigation组件来简化我的任务?
是否可能使用Android Jetpack Navigation组件导航到设置偏好的片段?我有一个带有多个嵌套Preference片段的设置屏幕。我想知道是否可以使用Android Jetpack Navigation组件来简化我的任务?
<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"
来标识导航目的地将非常方便;我只需要从导航图的XML文件中复制app:destination
。
然后,通过引用此preference.fragment
,可以按照以下方式在PREFERENCEFramgent
之间导航,文档中有说明。
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
}
...
}
然而,有一个小问题!在普通的活动中,R.id.FRAGMENT
表示活动视图中的占位符,您可以在其中将主要片段交换进出。当使用导航时,R.id.FRAGMENT
映射到 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?:"") }
是的,您可以在“偏好设置”片段中使用导航组件。
我也有一个主偏好设置片段,其中包含多个嵌套片段。对我而言,最好的方法是仅在偏好设置片段内导航,而无需任何活动。因此,我创建了onPreferenceClickListeners,并像从普通片段导航一样进行导航。
findPreference(getString(R.string.PREF_GN_BUTTON_MAIN)).setOnPreferenceClickListener(preference5 -> {
Navigation.findNavController(requireView()).navigate(R.id.another_settings_fragment);
return true;
});
onPreferenceStartFragment
,但我没有看到任何优点。我使用单个Activity架构。