Material Preferences
This library is dependent on KotPreferences, a library that is based on Flows
and Coroutines
and works with a 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
.
This is an UI addition to KotPreferences and 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 (KotPreferences)
- flow and coroutine based (KotPreferences)
- allows to observe single / some / all preferences (KotPreferences)
- provides suspending update functions (KotPreferences)
- provides a DSL for a
RecyclerView
based setting screen
COMPOSE VERSION
You can find a compose version of this library under https://github.com/MFlisar/ComposePreferences
IMPORTANT INFORMATION (2023-10-16)
I splitted up the library into KotPreferences
and this library. Check out the migration guide here
This split up was made because I created a new preferences library for compose which uses the same core modules!
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 {
val kotPreferences = "<LATEST-VERSION>"
val materialPreferences = "<LATEST-VERSION>"
// --------------
// KotPreferences
// --------------
// core module
implementation("com.github.MFlisar.KotPreferences:core:$kotPreferences")
// data store module
implementation("com.github.MFlisar.KotPreferences:datastore:$kotPreferences")
// encryption module
implementation("com.github.MFlisar.KotPreferences:encryption-aes:$kotPreferences")
// -------------------
// MaterialPreferences
// -------------------
// screen modules
implementation("com.github.MFlisar.MaterialPreferences:screen:$materialPreferences")
implementation("com.github.MFlisar.MaterialPreferences:screen-bool:$materialPreferences")
implementation("com.github.MFlisar.MaterialPreferences:screen-input:$materialPreferences")
implementation("com.github.MFlisar.MaterialPreferences:screen-choice:$materialPreferences")
implementation("com.github.MFlisar.MaterialPreferences:screen-color:$materialPreferences")
implementation("com.github.MFlisar.MaterialPreferences:screen-slider:$materialPreferences")
implementation("com.github.MFlisar.MaterialPreferences:screen-image:$materialPreferences")
}
The latest KotPreferences release can be found here The latest MaterialPreferences release can be found here
Screenshots
Example
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.
Documentation
For the documentation of how preferences work and can be used, please check out the documentation of KotPreferences
here
DEMO APP
Check the demo app for more informations.
This modules are placed inside the screen-*
artifacts.
Usage with build in settings activity (PREFFERED)
This is an activity with a toolbar and a back button and can be shown as following:
fun showDefaultSettingsActivity(activity: AppCompatActivity) {
SettingsActivity.start(activity, ScreenCreator)
}
@Parcelize
object ScreenCreator : SettingsActivity.IScreenCreator {
override fun createScreen(activity: AppCompatActivity, savedInstanceState: Bundle?, updateTitle: (title: String) -> Unit): PreferenceScreen {
return screen {
// ... set up your preference screen here
}
}
}
This uses a "trick" to provide a small and efficient parcelable setup via an object
to avoid any problems (either memory nor speed wise) with the parcel size limit and still provides a convenient and simple way to use this library without having to write your own settings activity.
Usage with a custom activity (ALTERNATIVE)
Alternatively you can simple extend BaseSettingsActivity
and implement the single abstract createScreen
function there s shown inside the CustomSettingsActivity and with this method you can of course also embed the settings screen inside any bigger layout.
Generally the manual approach works as simple as following:
- create the screen
- bind it to a
RecyclerView
- forward the back press event to the screen so that it can handle its internal backstack
Here's an example:
Example - Screen
Here's an example:
val screen = screen {
state = savedInstanceState
category {
title = "Test App Style".asText()
}
input(UserSettingsModel.name) {
title = "Name".asText()
}
switch(UserSettingsModel.alive) {
title = "Alive".asText()
}
subScreen {
title = "More".asText()
color(UserSettingsModel.hairColor) {
title = "Hair Color".asText()
}
input(UserSettingsModel.age) {
title = "Age".asText()
}
}
}
Check out the demo app code for more details and especially the screen definitions in the demo here:
Supported Settings
Following settings are supported already:
- Category
- Sub Screens (supports nesting)
- Checkbox
- Switch
- Input (text, number, password, ...)
- Buttons
- Color (w/o alpha)
- Slider (Seekbar)
And following features are supported:
- callback to check if a value is allowed to be changed (e.g. to only allow a change in the pro version)
- dependency on other preference (even with custom dependency evaluator)
- badges to display a badge next to a settings title
- restores list state automatically even in nested preferences
Default Settings
Some values can be defined globally and will be used by all preferences - those default values are stored in the PreferenceScreenConfig
object. You can change dafault values like following:
PreferenceScreenConfig.apply {
bottomSheet = true // default: false
maxLinesTitle = 1 // default: 1
maxLinesSummary = 3 // default: 3
}
Credits
Special thanks goes to ModernAndroidPreferences because I copied a few things from there, namely following:
- the root layout xml
- the
RecyclerView
animations - the badge idea and the badge drawable
- the basic idea for the DSL