-
-
Notifications
You must be signed in to change notification settings - Fork 381
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: implement PreferenceDelegate to simplify AppPrefs
Say goodbye to dizzy getters and setters. Also add support of Float, Set<String> and Enum<*> type.
- Loading branch information
1 parent
d0f1787
commit 310449e
Showing
9 changed files
with
239 additions
and
269 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
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
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
92 changes: 92 additions & 0 deletions
92
app/src/main/java/com/osfans/trime/data/prefs/PreferenceDelegate.kt
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
package com.osfans.trime.data.prefs | ||
|
||
import android.content.SharedPreferences | ||
import androidx.core.content.edit | ||
import kotlin.properties.ReadWriteProperty | ||
import kotlin.reflect.KProperty | ||
|
||
open class PreferenceDelegate<T : Any>( | ||
val sharedPreferences: SharedPreferences, | ||
val key: String, | ||
val defaultValue: T, | ||
) : ReadWriteProperty<Any?, T> { | ||
@Suppress("IMPLICIT_CAST_TO_ANY", "UNCHECKED_CAST") | ||
open fun getValue(fallbackKey: String): T { | ||
val finalKey = key.ifEmpty { fallbackKey } | ||
return try { | ||
when (defaultValue) { | ||
is Int -> sharedPreferences.getInt(finalKey, defaultValue) | ||
is Long -> sharedPreferences.getLong(finalKey, defaultValue) | ||
is Float -> sharedPreferences.getFloat(finalKey, defaultValue) | ||
is Boolean -> sharedPreferences.getBoolean(finalKey, defaultValue) | ||
is String -> sharedPreferences.getString(finalKey, defaultValue) ?: defaultValue | ||
is Set<*> -> sharedPreferences.getStringSet(finalKey, defaultValue as? Set<String>) | ||
else -> null | ||
} as T | ||
} catch (e: Exception) { | ||
setValue(fallbackKey, defaultValue) | ||
defaultValue | ||
} | ||
} | ||
|
||
open fun setValue( | ||
fallbackKey: String, | ||
value: T, | ||
) { | ||
val finalKey = key.ifEmpty { fallbackKey } | ||
sharedPreferences.edit { | ||
when (value) { | ||
is Int -> putInt(finalKey, value) | ||
is Long -> putLong(finalKey, value) | ||
is Float -> putFloat(finalKey, value) | ||
is Boolean -> putBoolean(finalKey, value) | ||
is String -> putString(finalKey, value) | ||
is Set<*> -> putStringSet(finalKey, value.map { it.toString() }.toHashSet()) | ||
} | ||
} | ||
} | ||
|
||
override fun getValue( | ||
thisRef: Any?, | ||
property: KProperty<*>, | ||
): T = getValue(property.name) | ||
|
||
override fun setValue( | ||
thisRef: Any?, | ||
property: KProperty<*>, | ||
value: T, | ||
) = setValue(property.name, value) | ||
|
||
interface Serializer<T : Any> { | ||
fun serialize(t: T): String | ||
|
||
fun deserialize(raw: String): T? | ||
} | ||
|
||
class SerializableDelegate<T : Any>( | ||
sharedPreferences: SharedPreferences, | ||
key: String, | ||
defaultValue: T, | ||
private val serializer: Serializer<T>, | ||
) : PreferenceDelegate<T>(sharedPreferences, key, defaultValue) { | ||
override fun setValue( | ||
fallbackKey: String, | ||
value: T, | ||
) { | ||
val finalKey = key.ifEmpty { fallbackKey } | ||
sharedPreferences.edit { putString(finalKey, serializer.serialize(value)) } | ||
} | ||
|
||
override fun getValue(fallbackKey: String): T { | ||
val finalKey = key.ifEmpty { fallbackKey } | ||
return try { | ||
sharedPreferences.getString(finalKey, null)?.let { | ||
serializer.deserialize(it) | ||
} ?: defaultValue | ||
} catch (e: Exception) { | ||
setValue(fallbackKey, defaultValue) | ||
defaultValue | ||
} | ||
} | ||
} | ||
} |
60 changes: 60 additions & 0 deletions
60
app/src/main/java/com/osfans/trime/data/prefs/PreferenceDelegateOwner.kt
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package com.osfans.trime.data.prefs | ||
|
||
import android.content.SharedPreferences | ||
|
||
abstract class PreferenceDelegateOwner( | ||
protected val sharedPreferences: SharedPreferences, | ||
) { | ||
protected fun int( | ||
key: String, | ||
defaultValue: Int, | ||
) = PreferenceDelegate(sharedPreferences, key, defaultValue) | ||
|
||
protected fun long( | ||
key: String, | ||
defaultValue: Long, | ||
) = PreferenceDelegate(sharedPreferences, key, defaultValue) | ||
|
||
protected fun float( | ||
key: String, | ||
defaultValue: Float, | ||
) = PreferenceDelegate(sharedPreferences, key, defaultValue) | ||
|
||
protected fun bool( | ||
key: String, | ||
defaultValue: Boolean, | ||
): PreferenceDelegate<Boolean> { | ||
return PreferenceDelegate(sharedPreferences, key, defaultValue) | ||
} | ||
|
||
protected fun string( | ||
key: String, | ||
defaultValue: String, | ||
): PreferenceDelegate<String> { | ||
return PreferenceDelegate(sharedPreferences, key, defaultValue) | ||
} | ||
|
||
protected fun stringSet( | ||
key: String, | ||
defaultValue: Set<String>, | ||
) = PreferenceDelegate(sharedPreferences, key, defaultValue) | ||
|
||
protected fun <T : Any> serializable( | ||
key: String, | ||
defaultValue: T, | ||
serializer: PreferenceDelegate.Serializer<T>, | ||
) = PreferenceDelegate.SerializableDelegate(sharedPreferences, key, defaultValue, serializer) | ||
|
||
protected inline fun <reified T : Enum<T>> enum( | ||
key: String, | ||
defaultValue: T, | ||
) = serializable( | ||
key, | ||
defaultValue, | ||
object : PreferenceDelegate.Serializer<T> { | ||
override fun serialize(t: T) = t.name | ||
|
||
override fun deserialize(raw: String) = enumValueOf<T>(raw.uppercase()) | ||
}, | ||
) | ||
} |
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
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
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
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