3

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.

Clandes
  • 61
  • 2
  • 7

2 Answers2

6

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.

Anatolii Shuba
  • 4,614
  • 1
  • 16
  • 17
4

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

dmapr
  • 349
  • 1
  • 7