PreferenceFragments是否不在同一个FragmentManager中? [英] PreferenceFragments not in the same FragmentManager?
问题描述
我们有一个 PreferenceFragmentCompat
,然后点击一个首选项,我们希望从当前的 PreferenceFragmentCompat
切换到新的 PreferenceFragmentCompat
.(要在新屏幕上进行某些设置).
We have a PreferenceFragmentCompat
, and with a tap on a preference, we want to switch from the current PreferenceFragmentCompat
to a new PreferenceFragmentCompat
. (To have certain settings on a new screen).
但是,无论我们尝试了什么,我们都会遇到以下错误:
However, regardless of what we have tried, we keep running into the following error:
片段声明的目标片段不属于此片段FragmentManager
Fragment declared target fragment that does not belong to this FragmentManager
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
}
}
PreferenceFragement1.kt
class PreferencesFragment1 : PreferenceFragmentCompat() {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.preferences1, rootKey)
}
}
PreferenceFragment2.kt
class PreferenceFragment2 : PreferenceFragmentCompat() {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.preferences2, rootKey)
}
}
Preferences1.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>
Preferences2.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">
</PreferenceScreen>
stacktrace显示以下内容:
The stacktrace shows the following:
java.lang.IllegalStateException: Fragment Preference2{496ebb9} (1b91d8df-58c0-485a-96f9-d392fcef528b) id=0x7f09008d} declared target fragment Preference1{b6337c1} (97aa1b0e-d5fa-4995-b0ba-e89ad0ea5ce0) id=0x7f09008d} that does not belong to this FragmentManager!
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1148)
at androidx.fragment.app.FragmentTransition.addToFirstInLastOut(FragmentTransition.java:1255)
at androidx.fragment.app.FragmentTransition.calculateFragments(FragmentTransition.java:1138)
at androidx.fragment.app.FragmentTransition.startTransitions(FragmentTransition.java:136)
at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1989)
at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1947)
at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1849)
at androidx.fragment.app.FragmentManager$4.run(FragmentManager.java:413)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6718)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:491)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
我们正在使用 androidx.preference:preference-ktx:1.1.1
.有人可以给我们一个简洁的解释,究竟是什么导致了这个问题,以及我们如何解决它?
We are using androidx.preference:preference-ktx:1.1.1
.
Can some give us a concise explanation what exactly is causing this problem, and how we can solve it?
我们已经查看了以下(相关)帖子,但没有成功:
We already looked at the following (related) posts, without any success:
- 片段声明的目标片段属于这个FragmentManager
- 如何使用新的Android-X API从当前版本中打开一个新的PreferenceFragment?
- https://developer.android.com/guide/topics/ui/settings/organize-your-settings
推荐答案
通过导航图创建片段时,它是 NavHostFragment
的子片段.具体来说,不是活动的 supportFragmentManager
.这就是为什么找不到目标片段的原因-您使用的是错误的FragmentManager.
When you create a Fragment via the navigation graph, it is a child fragment of the NavHostFragment
. It specifically is not the activity's supportFragmentManager
. This is why the target fragment isn't found - you're using the wrong FragmentManager.
但是,在使用导航时,不应使用 app:fragment
或 onPreferenceStartFragment
.相反,您的 PreferencesFragment1
应该在您的首选项上设置一个点击侦听器,并使其直接调用 navigate()
.
However, you should not use app:fragment
or onPreferenceStartFragment
when you're using Navigation. Instead, your PreferencesFragment1
should set a click listener on your Preference and have it call navigate()
directly.
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)
}
}
}
Preferences1.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"/>
</PreferenceCategory>
</PreferenceScreen>
这篇关于PreferenceFragments是否不在同一个FragmentManager中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!