Dialog inside Android Preferences.

Borama Apps
Apr 5 · 2 min read

This tutorial will show how to create simple Dialog inside Preferences.

We will be using PreferenceFragmentCompat, so first let’s import in module’s build.gradle and sync:

implementation "com.android.support:preference-v7:28.0.0"

Next create prefs.xml (inside xml subfolder of res folder). By default the new file will have content like this:

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">

</PreferenceScreen>

Important part here is to use replace PreferenceScreen with android.support.v7.preference.PreferenceScreen!

Now create SettingsFragment which extends PreferenceFragmentCompat and implement required onCreatePreferences:

// SettingsFragment.kt
class
SettingsFragment: PreferenceFragmentCompat() {

override fun onCreatePreferences(p0: Bundle?, p1: String?) {
setPreferencesFromResource(R.xml.prefs, p1)
}
}

In our MainActivity add SettingsFragment:

// MainActivity.kt
class
MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
supportFragmentManager
.beginTransaction()
.replace(android.R.id.content, SettingsFragment())
.commit()
}
}

Next let’s create DialogClearRecentSearches:

// DialogClearRecentSearches.kt
import
android.content.Context
import android.support.v7.preference.DialogPreference
import android.util.AttributeSet

class DialogClearRecentSearches(context: Context, attrs: AttributeSet?) : DialogPreference(context, attrs)

and add it to prefs.xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<co.borama.dialogpreferencesexample.DialogClearRecentSearches
android:key="pref_delete_recent_searches"
android:title="Delete Recent Searches"
android:negativeButtonText="No"
/>
</android.support.v7.preference.PreferenceScreen>

If we run the app now it will show the title “Delete Recent Searches” but when we click on it will crash with java.lang.IllegalArgumentException: Tried to display dialog for unknown preference type. Did you forget to override onDisplayPreferenceDialog()?

We need to add onDisplayPreferenceDialog() to SettingsFragment and to show our dialog we need to use PreferenceDialogFragmentCompat, so let’s implement it in DialogPrefCompat.kt

//DialogPrefCompat.kt
import android.os.Bundle
import android.support.v7.preference.PreferenceDialogFragmentCompat

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

Let’s implement onDisplayPreferenceDialog() inside SettingsFragment:

override fun onDisplayPreferenceDialog(preference: Preference?) {
val clearRecentDialog = preference as? DialogClearRecentSearches
if (clearRecentDialog != null) {
val dialogFragment = DialogPrefCompat.newInstance(clearRecentDialog.key)
dialogFragment.setTargetFragment(this, 0)
dialogFragment.positiveResult = {
Toast.makeText(activity, "yes", Toast.LENGTH_LONG).show()
}
dialogFragment.show(fragmentManager, null)
} else {
super.onDisplayPreferenceDialog(preference)
}
}

We pass positiveResult callback to verify that OK button works.

That’s it!

Full code here:

https://github.com/standinga/DialogPreferenceExample

Please check my IOS and Android apps!

Follow me on twitter :)

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade