setTargetFragment()
is deprecated in Java, and I don't understand the correct replacement for it as android documentation uses it and is outdated. I believe the FragmentManager
is the correct replacement for it. I am using the deprecated setTargetFragment
function in my settings Preferences to create multiple preference screens. To do so, I originally followed the guide here which confusingly uses setTargetFragment
in the example. Below is my code:
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()
}
}
Yes, using the support library Fragment along with the getSupportFragmentManager is the right thing to do.
This class was deprecated in API level 28. Use the Support Library DialogFragment for consistent behavior across all devices and access to Lifecycle. This class was deprecated in API level 28.
getFragmentManager() deprecation: The getFragmentManager() and requireFragmentManager() methods on Fragment have been deprecated and replaced with a single getParentFragmentManager() method, which returns the non-null FragmentManager the Fragment is added to (you can use isAdded() to determine if it is safe to call).
According to the Android documentation, a fragment is a part of applications user interface that is bound to an activity. Fragments have their lifecycle and layouts or UI components. Fragments help enrich your UI design, pass data between different screens, and adapt to different device configurations.
Include this dependency:
implementation 'androidx.fragment:fragment-ktx:1.3.0-beta01'
Use setFragmentResultListener
instead of 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
}
And in your fragment that returns a result:
// Insert result in a bundle
setFragmentResult("requestKey", bundle)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With