简体   繁体   中英

PreferenceDialog in PreferenceActivity - Target fragment must implement TargetFragment interface

I'm trying to implement a DialogPreference in a Preference activity. I achieved it but it seems setTargetFragment is marked as deprecated.

在此处输入图像描述

Here is my old code:

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

I wanted to replace it with setFragmentResultListener but I'm always getting "Target fragment must implement TargetFragment interface" exception.

Can someone help me?

Here is the complete code:


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"
    }
}

Thanks in advance.

I think the such behavour is related to the next Android bug:

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

It still not fixed for Preferences lib 1.2.0 (Nov 1, 2022). setTargetFragment() must be called even if lint says it is deprecated.

Doesn't look too promising: https://android-review.googlesource.com/c/platform/frameworks/support/+/1843122/8/preference/preference/src/main/java/androidx/preference/PreferenceDialogFragmentCompat.java just added @SuppressWarnings("deprecation") over the relevant code. I think that until PreferenceDialogFragmentCompat is switched over to the new API we're stuck calling setTargetFragment :(

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM