-
-
Save ND1010/35a3b1f39373b1793356bdb0ab397068 to your computer and use it in GitHub Desktop.
Make Android's SharedPreferences as simple as a field in kotlin.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.mypackage.myapp.prefs | |
import android.content.Context | |
import com.mypackage.myapp.appCtx | |
object MyPreferences : Preferences(name = "MyPrefsFileName") { | |
var userWantsFancyUi by BoolPref(Keys.FANCY_UI, false) | |
var isFcmTokenSent by BoolPref(Keys.FCM_TOKEN_SENT_TO_SERVER, false) | |
var eggTapsCount by LongPref(Keys.EGG_TAPS_COUNT, 0L) | |
object Keys { | |
const val FANCY_UI = "fancyUI" | |
const val FCM_TOKEN_SENT_TO_SERVER = "fcmTokenSent" | |
const val EGG_TAPS_COUNT = "eggTapsCount" | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.mypackage.myapp.prefs | |
import android.content.Context | |
import android.content.SharedPreferences | |
import com.google.android.agera.BaseObservable | |
import com.google.android.agera.Observable | |
import com.google.android.agera.Updatable | |
import com.mypackage.myapp.appCtx | |
abstract class ObservablePreferences(ctx: Context = appCtx, name: String) : Preferences(ctx, name), Observable { | |
private val changeListener by lazy { ChangesObservable() } | |
/** | |
* Updated before the update is dispatched. The value should be only used to check which | |
* preference changed. | |
*/ | |
var lastChangedKey = "" | |
private set | |
override fun addUpdatable(updatable: Updatable) = changeListener.addUpdatable(updatable) | |
override fun removeUpdatable(updatable: Updatable) = changeListener.removeUpdatable(updatable) | |
inner private class ChangesObservable : BaseObservable(), SharedPreferences.OnSharedPreferenceChangeListener { | |
override fun observableActivated() = prefs.registerOnSharedPreferenceChangeListener(this) | |
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) { | |
check(sharedPreferences in this@ObservablePreferences) | |
lastChangedKey = key | |
dispatchUpdate() | |
} | |
override fun observableDeactivated() = prefs.unregisterOnSharedPreferenceChangeListener(this) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.mypackage.myapp.prefs | |
import android.content.Context | |
import com.mypackage.myapp.appCtx | |
abstract class Preferences(ctx: Context = appCtx, name: String) { | |
private val prefs = ctx.getSharedPreferences(name, Context.MODE_PRIVATE) | |
operator fun contains(o: Any) = prefs === o | |
internal inner class BoolPref(key: String, defaultValue: Boolean) | |
: BoolPrefField(prefs, key, defaultValue) | |
internal inner class IntPref(key: String, defaultValue: Int) | |
: IntPrefField(prefs, key, defaultValue) | |
internal inner class FloatPref(key: String, defaultValue: Float) | |
: FloatPrefField(prefs, key, defaultValue) | |
internal inner class LongPref(key: String, defaultValue: Long) | |
: LongPrefField(prefs, key, defaultValue) | |
internal inner class StringPref(key: String, defaultValue: String) | |
: StringPrefField(prefs, key, defaultValue) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.mypackage.myapp.prefs | |
@file:Suppress("NOTHING_TO_INLINE") | |
import android.content.SharedPreferences | |
import kotlin.reflect.KProperty | |
internal abstract class BoolPrefField(private val prefs: SharedPreferences, | |
private val key: String, | |
defaultValue: Boolean) { | |
private var cachedValue = prefs.getBoolean(key, defaultValue) | |
inline operator fun getValue(thisRef: Any?, prop: KProperty<*>) = cachedValue | |
inline operator fun setValue(thisRef: Any?, prop: KProperty<*>, value: Boolean) { | |
cachedValue = value | |
prefs.edit().putBoolean(key, value).apply() | |
} | |
} | |
internal abstract class IntPrefField(private val prefs: SharedPreferences, | |
private val key: String, | |
defaultValue: Int) { | |
private var cachedValue = prefs.getInt(key, defaultValue) | |
inline operator fun getValue(thisRef: Any?, prop: KProperty<*>) = cachedValue | |
inline operator fun setValue(thisRef: Any?, prop: KProperty<*>, value: Int) { | |
cachedValue = value | |
prefs.edit().putInt(key, value).apply() | |
} | |
} | |
internal abstract class LongPrefField(private val prefs: SharedPreferences, | |
private val key: String, | |
defaultValue: Long) { | |
private var cachedValue = prefs.getLong(key, defaultValue) | |
inline operator fun getValue(thisRef: Any?, prop: KProperty<*>) = cachedValue | |
inline operator fun setValue(thisRef: Any?, prop: KProperty<*>, value: Long) { | |
cachedValue = value | |
prefs.edit().putLong(key, value).apply() | |
} | |
} | |
internal abstract class FloatPrefField(private val prefs: SharedPreferences, | |
private val key: String, | |
defaultValue: Float) { | |
private var cachedValue = prefs.getFloat(key, defaultValue) | |
inline operator fun getValue(thisRef: Any?, prop: KProperty<*>) = cachedValue | |
inline operator fun setValue(thisRef: Any?, prop: KProperty<*>, value: Float) { | |
cachedValue = value | |
prefs.edit().putFloat(key, value).apply() | |
} | |
} | |
internal abstract class StringPrefField(private val prefs: SharedPreferences, | |
private val key: String, | |
defaultValue: String) { | |
private var cachedValue = prefs.getString(key, defaultValue)!! | |
inline operator fun getValue(thisRef: Any?, prop: KProperty<*>) = cachedValue | |
inline operator fun setValue(thisRef: Any?, prop: KProperty<*>, value: String) { | |
cachedValue = value | |
prefs.edit().putString(key, value).apply() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment