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.