#android #android-fragments #androidx #android-preferences
#Android #android-фрагменты #androidx #android-настройки
Вопрос:
setTargetFragment()
устарел в Java, и я не понимаю правильной замены для него, поскольку документация Android использует его и устарела. Я считаю FragmentManager
, что это правильная замена для него. Я использую устаревшую setTargetFragment
функцию в настройках настроек для создания нескольких экранов настроек. Для этого я изначально следовал приведенному здесь руководству, которое ошибочно используется setTargetFragment
в примере. Ниже приведен мой код:
build.gradle (Module: app)
...
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'androidx.preference:preference:1.1.1'
...
MainActivity.kt
class MainActivity : AppCompatActivity() {
private lateinit var settingsButton: ImageButton
override fun onCreate(savedInstanceState: Bundle?) {
...
settingsButton = findViewById(R.id.settingsButtonMain)
settingsButton.setOnClickListener {
settingsClicked()
}
...
}
private fun settingsClicked() {
val settingsIntent = Intent(this, SettingsActivity::class.java)
startActivity(settingsIntent)
}
}
SettingsActivity.kt
class SettingsActivity : AppCompatActivity(), PreferenceFragmentCompat.OnPreferenceStartFragmentCallback {
override fun onCreate(savedInstanceState: Bundle?) {
...
supportFragmentManager.beginTransaction().replace(R.id.settings, SettingsFragment(this)).commit()
supportFragmentManager.addOnBackStackChangedListener {
if(supportFragmentManager.backStackEntryCount == 0) {
title = "App Settings"
}
}
supportActionBar?.setDisplayHomeAsUpEnabled(true)
...
}
class SettingsFragment(cont: Context) : PreferenceFragmentCompat() {
private var context1: Context = cont
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.root_preferences, rootKey)
}
}
class Screen2PreferencesFragment : PreferenceFragmentCompat() {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.screen2_preferences, null)
}
}
override fun onPreferenceStartFragment(caller: PreferenceFragmentCompat?, pref: Preference): Boolean {
val args: Bundle = pref.extras
val fragment: Fragment = supportFragmentManager.fragmentFactory.instantiate(classLoader, pref.fragment)
fragment.arguments = args
fragment.setTargetFragment(caller, 0) //TROUBLE AREA. WHAT IS THE CORRECT REPLACEMENT HERE?
supportFragmentManager.beginTransaction().replace(R.id.settings, fragment).addToBackStack(null).commit()
return true
}
override fun onSupportNavigateUp(): Boolean {
if(supportFragmentManager.popBackStackImmediate()) {
return true
}
return super.onSupportNavigateUp()
}
}
Комментарии:
Ответ №1:
Включите эту зависимость:
implementation 'androidx.fragment:fragment-ktx:1.3.0-beta01'
Используйте setFragmentResultListener
вместо setTargetFragment()
:
override fun onPreferenceStartFragment(caller: PreferenceFragmentCompat?, pref: Preference): Boolean {
val args: Bundle = pref.extras
val fragment: Fragment = supportFragmentManager.fragmentFactory.instantiate(classLoader, pref.fragment)
fragment.arguments = args
supportFragmentManager.beginTransaction().replace(R.id.settings, fragment).addToBackStack(null).commit()
supportFragmentManager.setFragmentResultListener("requestKey") { key, bundle ->
if (key == "requestKey") {
// Get result from bundle
}
}
return true
}
И в вашем фрагменте, который возвращает результат:
// Insert result in a bundle
setFragmentResult("requestKey", bundle)
Комментарии:
1.
setFragmentResultListener
неразрешен. Я полагаю, мне нужно реализовать интерфейс?2. Я думаю, я понял это. Поправьте меня, если я ошибаюсь.
setFragmentResultListener
на самом деле должно выглядеть такval result = "result" n setFragmentResult("requestKey", bundleOf("bundleKey" to result))
: nFragmentResultOwner
необходимо реализовать и переопределить классы здесь (новая строка не отображается в комментарии, поэтому я добавил n там, где она должна быть)3. Если он не решен, добавьте
import androidx.fragment.app.setFragmentResultListener
. Создайте пакет, используяbundleOf("bundleKey" to result)
и добавьте его в качестве параметраsetFragmentResult()
, как показано в ответе.4. Из моего тестирования это определенно требует реализации FragmentResultOwner. Он не работает без или только с предлагаемым импортом (который кажется недействительным). Я ценю помощь.
Ответ №2:
Для нерешенной проблемы при попытке использовать setFragmentResult, ссылающейся на приведенный выше ответ, вы можете попробовать использовать FragmentManager следующим образом.
Это для Xamarin:
ParentFragmentManager.SetFragmentResult("requestKey", bundle);