Skip to content

Instantly share code, notes, and snippets.

@ologe
Created December 10, 2021 14:55
Show Gist options
  • Save ologe/a8dc4480eb42003bdfc13f42194fa650 to your computer and use it in GitHub Desktop.
Save ologe/a8dc4480eb42003bdfc13f42194fa650 to your computer and use it in GitHub Desktop.
interface Preference<T> {
fun get(): T
fun set(value: T)
fun observe(): Flow<T>
fun reset()
}
fun <T : Any> SharedPreferences.preference(
key: String,
default: T
): Preference<T> {
return PreferenceImpl(this, key, default)
}
private class PreferenceImpl<T : Any>(
private val preferences: SharedPreferences,
private val key: String,
private val default: T,
) : Preference<T> {
override fun get(): T {
return getItem(key, default)
}
@Suppress("UNCHECKED_CAST")
override fun set(value: T) {
preferences.edit(commit = true) {
when (value) {
is Boolean -> putBoolean(key, value)
is Int -> putInt(key, value)
is Long -> putLong(key, value)
is Float -> putFloat(key, value)
is String -> putString(key, value)
is Set<*> -> putStringSet(key, value as Set<String>)
}
}
}
override fun observe(): Flow<T> {
val flow = MutableStateFlow(getItem(key, default))
val listener = SharedPreferences.OnSharedPreferenceChangeListener { _, k ->
if (key == k) {
flow.value = getItem(key, default)
}
}
preferences.registerOnSharedPreferenceChangeListener(listener)
return flow.onCompletion {
preferences.unregisterOnSharedPreferenceChangeListener(listener)
}
}
override fun reset() {
set(default)
}
@Suppress("UNCHECKED_CAST")
private fun getItem(key: String, default: T): T {
return (preferences.all[key] ?: default) as T
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment