Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to replace setTargetFragment() now that it is deprecated

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()
    }
}
like image 570
Tom Avatar asked Nov 17 '20 04:11

Tom


People also ask

What can I use instead of getFragmentManager?

Yes, using the support library Fragment along with the getSupportFragmentManager is the right thing to do.

Are fragments deprecated?

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.

What is getFragmentManager?

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).

What Fragment in android?

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.


1 Answers

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)
like image 134
Saurabh Thorat Avatar answered Oct 07 '22 14:10

Saurabh Thorat