Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

enter image description here

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.

like image 339
Clandes Avatar asked Sep 18 '25 21:09

Clandes


2 Answers

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

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

It is still not fixed for Preferences library v.1.2.0 (Nov 1, 2022).

setTargetFragment() must be called even if Lint says the method is deprecated.

like image 100
Anatolii Shuba Avatar answered Sep 21 '25 12:09

Anatolii Shuba


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 :(

like image 35
dmapr Avatar answered Sep 21 '25 14:09

dmapr