Skip to content

Commit

Permalink
Allow PreferenceScreens to have a key
Browse files Browse the repository at this point in the history
Being able to tag PreferenceScreens with a key is useful for organizational reasons, even if they don't persist any data to the SharedPreferences.
For backwards compatibility and flexibility, the default key for PreferenceScreens is still an empty string.
The root screen, however, now gets a special reserved key, which may not be used for sub-screens (but could theoretically still be used for Preferences, this is highly discouraged though). With that root key, it will be possible to do better screen traversal in the future.
  • Loading branch information
Maxr1998 committed Apr 6, 2020
1 parent 60b5fa0 commit 5c92d75
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 6 deletions.
15 changes: 11 additions & 4 deletions library/src/main/java/de/Maxr1998/modernpreferences/Preferences.kt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import androidx.annotation.LayoutRes
import androidx.annotation.StringRes
import androidx.core.content.edit
import androidx.core.view.isVisible
import de.Maxr1998.modernpreferences.helpers.KEY_ROOT_SCREEN
import de.Maxr1998.modernpreferences.preferences.CollapsePreference
import de.Maxr1998.modernpreferences.preferences.TwoStatePreference
import java.util.concurrent.atomic.AtomicBoolean
Expand Down Expand Up @@ -286,7 +287,7 @@ open class Preference(key: String) : AbstractPreference(key) {
* - Every [PreferenceScreen] can be bound to a different [SharedPreferences] file
* - Even though you can change the [enabled] or the [persistent] state, it doesn't have any effect in this instance
*/
class PreferenceScreen private constructor(builder: Builder) : Preference("") {
class PreferenceScreen private constructor(builder: Builder) : Preference(builder.key) {
internal val prefs = builder.prefs
private val keyMap: Map<String, Preference> = builder.keyMap
private val preferences: List<Preference> = builder.preferences
Expand Down Expand Up @@ -349,8 +350,9 @@ class PreferenceScreen private constructor(builder: Builder) : Preference("") {
adapter?.notifyItemRangeChanged(position, itemCount)
}

class Builder(private var context: Context?) : AbstractPreference("") {
constructor(builder: Builder) : this(builder.context)
class Builder private constructor(private var context: Context?, key: String) : AbstractPreference(key) {
constructor(context: Context?) : this(context, KEY_ROOT_SCREEN)
constructor(builder: Builder, key: String = "") : this(builder.context, key)

/**
* The filename to use for the [SharedPreferences] of this [PreferenceScreen]
Expand Down Expand Up @@ -379,10 +381,15 @@ class PreferenceScreen private constructor(builder: Builder) : Preference("") {
* [subScreen][de.Maxr1998.modernpreferences.helpers.subScreen] for this.
*/
fun addPreferenceItem(p: Preference) {
if (p.key == KEY_ROOT_SCREEN)
throw UnsupportedOperationException("" +
"A screen with key '$KEY_ROOT_SCREEN' cannot be added as a sub-screen! " +
"If you are trying to add a sub-screen to your preferences model, " +
"use the `subScreen {}` function.")
if (p.key.isEmpty() && p !is PreferenceScreen)
throw UnsupportedOperationException("Preference key may not be empty!")

if (p is PreferenceScreen || keyMap.put(p.key, p) == null)
if (p.key.isEmpty() || keyMap.put(p.key, p) == null)
preferences.add(p)
else throw UnsupportedOperationException("A preference with this key is already in the screen!")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ inline fun screen(context: Context?, block: PreferenceScreen.Builder.() -> Unit)

val emptyScreen: PreferenceScreen by lazy { screen(null) {} }

inline fun PreferenceScreen.Builder.subScreen(block: PreferenceScreen.Builder.() -> Unit) {
addPreferenceItem(PreferenceScreen.Builder(this).apply(block).build())
inline fun PreferenceScreen.Builder.subScreen(key: String = "", block: PreferenceScreen.Builder.() -> Unit) {
addPreferenceItem(PreferenceScreen.Builder(this, key).apply(block).build())
}

// Preference DSL functions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ package de.Maxr1998.modernpreferences.helpers

import android.widget.SeekBar

const val KEY_ROOT_SCREEN = "root"

internal fun SeekBar.onSeek(callback: (Int, Boolean) -> Unit) {
setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
private var changed = false
Expand Down

0 comments on commit 5c92d75

Please sign in to comment.