【问题标题】:How to replace setTargetFragment() now that it is deprecated不推荐使用 setTargetFragment() 后如何替换它
【发布时间】:2020-11-17 04:48:02
【问题描述】:

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


    【解决方案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)
    

    【讨论】:

    • setFragmentResultListener 未解决。我想我需要实现一个接口?
    • 我想我明白了。如果我错了,请纠正我。 setFragmentResultListener 实际上应该看起来像这样 val result = "result" \n setFragmentResult("requestKey", bundleOf("bundleKey" to result)) \n FragmentResultOwner 需要实现并覆盖 here 类(新行没有在评论中显示,所以我在应该的地方添加了 \n)
    • 如果未解决,请添加import androidx.fragment.app.setFragmentResultListener。使用bundleOf("bundleKey" to result) 创建一个捆绑包,并将其作为参数添加到setFragmentResult(),如答案中所示。
    • 从我的测试来看,这肯定需要实现'FragmentResultOwner'。如果没有或仅使用建议的导入(这似乎无效),它就不起作用。感谢您的帮助。
    【解决方案2】:

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

    这是给 Xamarin 的:

    ParentFragmentManager.SetFragmentResult("requestKey", bundle);
    

    【讨论】:

      猜你喜欢
      • 2021-07-29
      • 2016-02-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-31
      • 1970-01-01
      相关资源
      最近更新 更多