我们可以将Android Jetpack导航组件与“设置”偏好设置一起使用吗?

时间:2019-07-10 12:10:18

标签: android kotlin android-preferences android-jetpack-navigation

是否可以使用Android Jetpack导航组件导航“设置”偏好设置的片段?我有一个带有多个嵌套首选项片段的“设置”屏幕。我想知道使用Android Jetpack导航组件来完成任务是否可行?

2 个答案:

答案 0 :(得分:0)

google文档指出,现在不建议使用首选项的层次嵌套,而建议使用片段间导航;结构ng build --prod现已发布。

文档建议使用优先选项替换嵌套的<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> 标识导航目的地,那将非常方便;我只是从导航图的XML文件中复制app:destination="@+id/SUBPreferenceFragment"

然后可以通过引用以下app:destination来在PREFERENCEFramgent之间导航,如下所示

preference.fragment

但是有一个小的Snafoo!正常活动中的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有更好的口号,请编辑问题或相应地发表评论,以便我更新答案。

答案 1 :(得分:0)

是的,您可以在首选项片段中使用导航组件。

我还有一个带有多个嵌套片段的主要优先片段。对我而言,最好的方法是在首选项片段中进行导航而无需任何活动。因此,我创建了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之类的ID一起使用,要安全一些。

我尝试在活动中覆盖onPreferenceStartFragment,但看不到它的任何优点。我使用单一活动架构。