如何替换 setTargetFragment() 既然它已被弃用

问题描述 投票:0回答:3

setTargetFragment()
在Java中已被弃用,我不明白它的正确替代品,因为android文档使用它并且已经过时了。我相信
FragmentManager
是它的正确替代品。我在设置首选项中使用已弃用的
setTargetFragment
功能来创建多个首选项屏幕。为此,我最初遵循了指南here,该指南在示例中使用了
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()
    }
}
android android-fragments androidx android-preferences
3个回答
11
投票

包含此依赖项:

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)

0
投票

对于参考上面答案尝试使用 setFragmentResult 时未解决的问题,您可以尝试使用fragmentManager,如下所示。

这是 Xamarin 的:

ParentFragmentManager.SetFragmentResult("requestKey", bundle);

0
投票

2024 年 1 月

我在两个 DialogFragment(父级和子级)中使用了 setFragmentResultListener,下面的代码基于此。我认为对于普通片段它的工作方式是相同的。

摇篮:

implementation 'androidx.fragment:fragment-ktx:1.6.2'

父DialogFragment中的onCreateDialog: 为parentFragmentManager设置FragmentResultListener。 请记住使用相同的片段管理器启动子片段!

...
parentFragmentManager.setFragmentResultListener("requestKey", this) { key, bundle ->
    val result = bundle.getString("myKey")
    //result is a string passed by child fragment
}

binding.someButton.setOnClickListener {
    val dialog = ChildDialogFragment()
    dialog.show(parentFragment.parentFragmentManager, "someTag")
}
...

子对话框片段

我将在单击按钮时将字符串值传递给父片段。

binding.someOtherButton.setOnClickListener {
    val stringToPass = "blablabla"
    val bundle = Bundle().apply {
        putString("myKey", result)
    }
    parentFragmentManager.setFragmentResult("requestKey", bundle)
}

享受吧!

© www.soinside.com 2019 - 2024. All rights reserved.