android - 我们可以使用带有设置首选项的 Android Jetpack 导航组件吗?

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

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

最佳答案

谷歌文档指出,偏好的分层嵌套现已弃用,取而代之的是 fragment 间导航;那就是结构<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 之间导航通过引用此 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在正常 Activity 中代表 Activity View 中的占位符,其中人们将交换主要 fragment 以不存在。使用导航时 R.id.FRAGMENT映射到 R.id.NAVIGATION并且上面的代码用偏好交换了整个导航 fragment 。对于使用导航的 Activity ,需要重新制定。

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?:"") }然后请相应地编辑问题或发表评论,以便我更新答案。

关于android - 我们可以使用带有设置首选项的 Android Jetpack 导航组件吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56970412/

相关文章:

java - 在android中的gridview底部添加一个按钮

android - 使用 android Picasso 或 Glide 滚动时出现卡顿效果

android - 水平 recylerview 的同步滚动与 viewpager 滚动

Android:如何从首选项标题启动 Activity ?

java - android - 从/res/raw文件夹中检索所有文件作为文件类型

kotlin - 有没有办法使用协程获得FixedTreadPool 行为?

android - Gradle 构建在本地机器上工作但在 Jenkins CI 服务器上失败?

android - 没有 fragment 的首选项标题标题?

android - 如何将空白图标空间添加到 preferencefragment

kotlin - Kotest 设置问题, 'unresolved reference'