PreferenceActivity 中的 PreferenceDialog - 目标片段必须实现 TargetFragment 接口

Cla*_*des 4 preferences dialog-preference kotlin

我正在尝试在首选项活动中实现 DialogPreference。我实现了它,但似乎 setTargetFragment 被标记为已弃用。

在此输入图像描述

这是我的旧代码:

override fun onDisplayPreferenceDialog(preference: Preference?) {
            val clearStatsDialog = preference as? DialogPreferenceClearStats
            if (clearStatsDialog != null) {
                val dialogFragment = DialogPrefCompat.newInstance(clearStatsDialog.key)
                dialogFragment.setTargetFragment(this, 0)
                dialogFragment.positiveResult = {
                    Toast.makeText(activity, "yes", Toast.LENGTH_LONG).show()
                }
                dialogFragment.show(this.parentFragmentManager, null)
            } else {
                super.onDisplayPreferenceDialog(preference)
            }
        }
Run Code Online (Sandbox Code Playgroud)

我想用 setFragmentResultListener 替换它,但我总是收到“目标片段必须实现 TargetFragment 接口”异常。

有人能帮我吗?

这是完整的代码:


import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.util.AttributeSet
import android.view.View
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.preference.DialogPreference
import androidx.preference.Preference
import androidx.preference.PreferenceDialogFragmentCompat
import androidx.preference.PreferenceFragmentCompat
import com.workout.intervaltimer.R
import com.workout.intervaltimer.util.WorkoutTimerUtil


class DialogPreferenceClearStats(context: Context, attrs: AttributeSet?) : DialogPreference(context, attrs), DialogPreference.TargetFragment {
    override fun <T : Preference?> findPreference(key: CharSequence): T? {
        TODO("Not yet implemented")
    }
}

class DialogPrefCompat : PreferenceDialogFragmentCompat() {
    lateinit var positiveResult: ()->Unit

    override fun onDialogClosed(positiveResult: Boolean) {
        if (positiveResult) {
            positiveResult()
        }
    }

    companion object {
        fun newInstance(key: String): DialogPrefCompat {
            val fragment = DialogPrefCompat()
            val bundle = Bundle(1)
            bundle.putString(PreferenceDialogFragmentCompat.ARG_KEY, key)
            fragment.arguments = bundle
            return fragment
        }
    }
}

class SettingsActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.settings_activity)
        if (savedInstanceState == null) {
            supportFragmentManager
                    .beginTransaction()
                    .replace(R.id.settings, SettingsFragment())
                    .commit()
        }
        supportActionBar?.setDisplayHomeAsUpEnabled(true)
    }

    class SettingsFragment : PreferenceFragmentCompat() {
        override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
            setPreferencesFromResource(R.xml.root_preferences, rootKey)
        }

        override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
            super.onViewCreated(view, savedInstanceState)

            this.parentFragmentManager.setFragmentResultListener("requestKey", viewLifecycleOwner) { requestKey, bundle ->
                val dialogFragment = DialogPrefCompat.newInstance("clearStatsDialog.key")
                dialogFragment.positiveResult = {
                    Toast.makeText(activity, "yes", Toast.LENGTH_LONG).show()
                }
                dialogFragment.show(this.parentFragmentManager, null)
            }
        }

        override fun onDisplayPreferenceDialog(preference: Preference?) {
            val clearStatsDialog = preference as? DialogPreferenceClearStats
            if (clearStatsDialog != null) {
                this.parentFragmentManager.setFragmentResult("requestKey", Bundle())
            }
        }

        override fun onPreferenceTreeClick(preference: Preference?): Boolean {
            //It should be possible to launchs activities and websites from xml intent but I didn't achieve it.
            when (preference!!.key) {
                getString(R.string.force_dark_theme) -> {
                    WorkoutTimerUtil.setDayNightThemeForApp(requireActivity().applicationContext)
                }

                getString(R.string.third_party_software) -> {
                    val intent = Intent(Intent.ACTION_VIEW)
                    intent.data = Uri.parse(WEB_THIRD_PARTY_SOFTWARE)
                    startActivity(intent)
                }

                getString(R.string.terms_conditions) -> {
                    val intent = Intent(Intent.ACTION_VIEW)
                    intent.data = Uri.parse(WEB_TERMS)
                    startActivity(intent)
                }

                getString(R.string.privacy_policy) -> {
                    val intent = Intent(Intent.ACTION_VIEW)
                     intent.data = Uri.parse(WEB_PRIVACY_POLICY)
                    startActivity(intent)
                }
            }

            return super.onPreferenceTreeClick(preference)
        }
    }

    companion object {
        const val WEB_THIRD_PARTY_SOFTWARE = "https://sites.google.com/view/that-third-party-software"
        const val WEB_TERMS = "https://sites.google.com/view/that-terms-conditions"
        const val WEB_PRIVACY_POLICY = "https://sites.google.com/view/that-privacy-policy"
    }
}
Run Code Online (Sandbox Code Playgroud)

提前致谢。

Ana*_*uba 7

我认为这种行为与下一个 Android bug 有关:

https://issuetracker.google.com/issues/181793702

Preferences 库 v.1.2.0(2022 年 11 月 1 日)的问题仍未修复。

即使 Lint 表示不推荐使用该方法,也必须调用setTargetFragment() 。