Preference via delegates + JetPack DataStore Storage + DSL for RecyclerView
MaterialPreferences
This library is based on Flows
and Coroutines
and works with the provided DataStore Storage or even with a custom storage implementation.
It supports LiveData
by default as Flows
can easily be converted to LiveData
. Preferences are elegantly declared via delegates
.
Additionally the preference-screen module provides a DSL to easily set up RecyclerView
based preference screens.
It also supports custom extensions for custom preference screens.
Following are the key features:
- define preferences elegantly via delegates
- flow and coroutine based
- allows to observe single / some / all preferences
- provides suspending update functions
- provides a DSL for a
RecyclerView
based setting screen
Core
With this library you can declare preferences via kotlin delegates
,and observe and update them via kotlin Flows
. This works with any storage implementation, an implementation for JetPack DataStore is provided already.
1/4 Define preferences:
object UserSettingsModel : SettingsModel(DataStoreStorage(name = "user")) {
// Basic
val name by stringPref("User")
val alive by boolPref(true)
val hairColor by intPref(Color.parseColor("#A52A2A"))
val age by intPref(40)
val income by floatPref(50000f)
val dayOfBirth by longPref(0L)
// Sets
val childrenAges by intSetPref(setOf(20, 18, 16))
val childrenIncomes by floatSetPref(setOf(30000f, 10000f, 0f))
val childrenDaysOfBirth by longSetPref(setOf(0L, 0L, 0L))
// Enum
val car by enumPref(Car.Tesla)
// custom class - provide a custom converter (String <=> Class)
val testClass by anyPref(TestClass.CONVERTER, TestClass())
}
2/4 Observe/Read preferences:
// 1) simply observe a setting
UserSettingsModel.name.observe(lifecycleScope) {
L.d { "name = $it"}
}
// 2) direct read (not recommended if not necessary but may be useful in many cases => simply returns flow.first() in a blocking way)
val name = UserSettingsModel.name.value
// 3) observe a setting once
UserSettingsModel.name.observeOnce(lifecycleScope) {
L.d { "name = $it"}
}
// 4) observe ALL settings
UserSettingsModel.changes.onEach {
L.d { "[ALL SETTINGS OBSERVER] Setting '${it.setting.key}' changed its value to ${it.value}" }
}.launchIn(lifecycleScope)
// 5) observe SOME settings
UserSettingsModel.changes´
.filter {
it.setting == UserSettingsModel.name ||
it.setting == UserSettingsModel.age
}.onEach {
// we know that either the name or the age changes
L.d { "[SOME SETTINGS OBSERVER] Setting '${it.setting.key}' changed its value to ${it.value}" }
}.launchIn(lifecycleScope)
// 6) read multiple settings in a suspending way
lifecycleScope.launch(Dispatchers.IO) {
val name = UserSettingsModel.childName1.flow.first()
val alive = DemoSettingsModel.alive.flow.first()
val hairColor = DemoSettingsModel.hairColor.flow.first()
withContext(Dispatchers.Main) {
textView.text = "Informations: $name, $alive, $hairColor"
}
}
3/4 Lifedata:
val lifedata = UserSettingsModel.name.flow.asLiveData()
4/4 Update preferences:
lifecycleScope.launch(Dispatchers.IO) {
UserSettingsModel.name.update("Some new name")
UserSettingsModel.age.update(30)
}
Storage
The Storage
is an abstraction to support any storage implementation. The datastore
module provides an implementation based on the Android JetPack DataStore.
Preference Screen
The preference-screen* modules allow you to create preference screens like following easily via DSL.
Gradle (via JitPack.io)
- add jitpack to your project's
build.gradle
:
repositories {
maven { url "https://jitpack.io" }
}
- add the compile statement to your module's
build.gradle
:
dependencies {
// core module
implementation "com.github.MFlisar.MaterialPreferences:core:<LATEST-VERSION>"
// data store module
implementation "com.github.MFlisar.MaterialPreferences:datastore:<LATEST-VERSION>"
// screen modules
implementation "com.github.MFlisar.MaterialPreferences:screen:<LATEST-VERSION>"
implementation "com.github.MFlisar.MaterialPreferences:screen-input:<LATEST-VERSION>"
implementation "com.github.MFlisar.MaterialPreferences:screen-choice:<LATEST-VERSION>"
implementation "com.github.MFlisar.MaterialPreferences:screen-color:<LATEST-VERSION>"
}