Android 首选项片段不在同一FragmentManager中?

Android 首选项片段不在同一FragmentManager中?,android,kotlin,mobile,fragment,fragmentmanager,Android,Kotlin,Mobile,Fragment,Fragmentmanager,我们有一个首选项FragmentCompat,点击一个首选项,我们想从当前的首选项FragmentCompat切换到一个新的首选项FragmentCompat。(在新屏幕上进行某些设置) 但是,无论我们尝试了什么,我们始终会遇到以下错误: 片段声明的目标片段不属于此 碎片管理器 MainActivity.kt class MainActivity : AppCompatActivity(), ActivityCompat.OnRequestPermissionsResultCallback, P

我们有一个
首选项FragmentCompat
,点击一个首选项,我们想从当前的
首选项FragmentCompat
切换到一个新的
首选项FragmentCompat
。(在新屏幕上进行某些设置)

但是,无论我们尝试了什么,我们始终会遇到以下错误:

片段声明的目标片段不属于此 碎片管理器

MainActivity.kt

class MainActivity : AppCompatActivity(), ActivityCompat.OnRequestPermissionsResultCallback, PreferenceFragmentCompat.OnPreferenceStartFragmentCallback {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val navView: BottomNavigationView = findViewById(R.id.nav_view)

        val navController = findNavController(R.id.nav_host_fragment)
        // Passing each menu ID as a set of Ids because each
        // menu should be considered as top level destinations.
        val appBarConfiguration = AppBarConfiguration(
            setOf(
                R.id.navigation_home, R.id.navigation_dashboard, R.id.navigation_preferences
            )
        )

        setupActionBarWithNavController(navController, appBarConfiguration)
        navView.setupWithNavController(navController)
    }

    override fun onPreferenceStartFragment(caller: PreferenceFragmentCompat, pref: Preference): Boolean {
        val args = pref.extras
        val fragment = supportFragmentManager.fragmentFactory.instantiate(
            classLoader,
            pref.fragment)
        fragment.arguments = args
        fragment.setTargetFragment(caller, 0)
        // Replace the existing Fragment with the new Fragment
        supportFragmentManager.beginTransaction()
            .replace(R.id.nav_host_fragment, fragment)
            .addToBackStack(null)
            .commit()
        return true
    }
}
class PreferencesFragment1 : PreferenceFragmentCompat() {

    override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
        setPreferencesFromResource(R.xml.preferences1, rootKey)
    }
}
class PreferenceFragment2 : PreferenceFragmentCompat() {

    override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
        setPreferencesFromResource(R.xml.preferences2, rootKey)
    }
}
首选框架1.kt

class MainActivity : AppCompatActivity(), ActivityCompat.OnRequestPermissionsResultCallback, PreferenceFragmentCompat.OnPreferenceStartFragmentCallback {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val navView: BottomNavigationView = findViewById(R.id.nav_view)

        val navController = findNavController(R.id.nav_host_fragment)
        // Passing each menu ID as a set of Ids because each
        // menu should be considered as top level destinations.
        val appBarConfiguration = AppBarConfiguration(
            setOf(
                R.id.navigation_home, R.id.navigation_dashboard, R.id.navigation_preferences
            )
        )

        setupActionBarWithNavController(navController, appBarConfiguration)
        navView.setupWithNavController(navController)
    }

    override fun onPreferenceStartFragment(caller: PreferenceFragmentCompat, pref: Preference): Boolean {
        val args = pref.extras
        val fragment = supportFragmentManager.fragmentFactory.instantiate(
            classLoader,
            pref.fragment)
        fragment.arguments = args
        fragment.setTargetFragment(caller, 0)
        // Replace the existing Fragment with the new Fragment
        supportFragmentManager.beginTransaction()
            .replace(R.id.nav_host_fragment, fragment)
            .addToBackStack(null)
            .commit()
        return true
    }
}
class PreferencesFragment1 : PreferenceFragmentCompat() {

    override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
        setPreferencesFromResource(R.xml.preferences1, rootKey)
    }
}
class PreferenceFragment2 : PreferenceFragmentCompat() {

    override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
        setPreferencesFromResource(R.xml.preferences2, rootKey)
    }
}
首选片段2.kt

class MainActivity : AppCompatActivity(), ActivityCompat.OnRequestPermissionsResultCallback, PreferenceFragmentCompat.OnPreferenceStartFragmentCallback {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val navView: BottomNavigationView = findViewById(R.id.nav_view)

        val navController = findNavController(R.id.nav_host_fragment)
        // Passing each menu ID as a set of Ids because each
        // menu should be considered as top level destinations.
        val appBarConfiguration = AppBarConfiguration(
            setOf(
                R.id.navigation_home, R.id.navigation_dashboard, R.id.navigation_preferences
            )
        )

        setupActionBarWithNavController(navController, appBarConfiguration)
        navView.setupWithNavController(navController)
    }

    override fun onPreferenceStartFragment(caller: PreferenceFragmentCompat, pref: Preference): Boolean {
        val args = pref.extras
        val fragment = supportFragmentManager.fragmentFactory.instantiate(
            classLoader,
            pref.fragment)
        fragment.arguments = args
        fragment.setTargetFragment(caller, 0)
        // Replace the existing Fragment with the new Fragment
        supportFragmentManager.beginTransaction()
            .replace(R.id.nav_host_fragment, fragment)
            .addToBackStack(null)
            .commit()
        return true
    }
}
class PreferencesFragment1 : PreferenceFragmentCompat() {

    override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
        setPreferencesFromResource(R.xml.preferences1, rootKey)
    }
}
class PreferenceFragment2 : PreferenceFragmentCompat() {

    override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
        setPreferencesFromResource(R.xml.preferences2, rootKey)
    }
}
首选项1.xml

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <PreferenceCategory
        android:title="Category"
        app:iconSpaceReserved="false">

        <Preference
            app:key="pref2"
            app:iconSpaceReserved="false"
            android:title="Open"
            app:fragment="com.testapp.ui.preferences.Preference2"/>

    </PreferenceCategory>
</PreferenceScreen>
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
</PreferenceScreen>
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <PreferenceCategory
        android:title="Category"
        app:iconSpaceReserved="false">

        <Preference
            app:key="pref2"
            app:iconSpaceReserved="false"
            android:title="Open"/>

    </PreferenceCategory>
</PreferenceScreen>
我们使用的是
androidx。首选项:preference ktx:1.1.1
。 一些人能否给我们一个简洁的解释,到底是什么导致了这个问题,以及我们如何解决它

我们已经查看了以下(相关)帖子,但没有成功:


通过导航图创建片段时,它是
NavHostFragment
的子片段。具体来说,它不是活动的
supportFragmentManager
。这就是为什么找不到目标片段-您使用了错误的FragmentManager

但是,在使用导航时,不应使用
app:fragment
onPreferenceStartFragment
。相反,您的
首选项Fragment1
应该在您的首选项上设置一个单击侦听器,并让它直接调用
navigate()

class PreferencesFragment1 : PreferenceFragmentCompat() {

    override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
        setPreferencesFromResource(R.xml.preferences1, rootKey)
        findPreference<Preference>("pref2")?.setOnPreferenceClickListener {
            // Use whatever ID that is associated with
            // PreferenceFragment2 in your navigation graph
            findNavController().navigate(R.id.pref2)
        }
    }
}
类首选项Fragment1:PreferenceFragmentCompat(){
重写FunonCreatePreferences(savedInstanceState:Bundle?,rootKey:String?){
setPreferencesFromResource(R.xml.preferences1,rootKey)
FindReference(“pref2”)?。设置首选项单击侦听器{
//使用与关联的任何ID
//导航图中的首选项片段2
findNavController().navigate(R.id.pref2)
}
}
}
首选项1.xml

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <PreferenceCategory
        android:title="Category"
        app:iconSpaceReserved="false">

        <Preference
            app:key="pref2"
            app:iconSpaceReserved="false"
            android:title="Open"
            app:fragment="com.testapp.ui.preferences.Preference2"/>

    </PreferenceCategory>
</PreferenceScreen>
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
</PreferenceScreen>
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <PreferenceCategory
        android:title="Category"
        app:iconSpaceReserved="false">

        <Preference
            app:key="pref2"
            app:iconSpaceReserved="false"
            android:title="Open"/>

    </PreferenceCategory>
</PreferenceScreen>

是的,谢谢您的回答!顺便说一下,作为谷歌的一名员工,我想知道这些文档是否可以在某个时候更新?概述部分讨论了如何使用Jetpack库中的PreferenceFragmentCompat,但当我们谈到上面关于子首选项屏幕的部分时,我们讨论的是覆盖活动方法等的“旧”方法,并且没有关于在Jetpack/导航组件世界中实现嵌套设置屏幕的指导。