Material Preferences

A beautiful and extensible API for bulding preferences screen.

? Installation

Download

Add this in app's build.gradle file:

implementation 'com.github.imangazalievm.material-prefs:core:<version>'
implementation 'com.github.imangazalievm.material-prefs:dialogs:<version>'
implementation 'com.github.imangazalievm.material-prefs:date-time:<version>'
implementation 'com.github.imangazalievm.material-prefs:color-picker:<version>'
Groovy

⭐ Features

  • Convenient and extensible DSL
  • Flexible appearance settings
  • Unified view on Lollipop and Pre-Lollipop
  • Ability to use custom storage
  • Default prefs values
  • Light and dark themes

? Usage

To start using the library you need to do 3 simple steps:

  1. Add MaterialPreferencesView in your layout
  2. Provide preferences storage:

    3.1 Default storage - DefaultPreferencesStorage

    3.1 Any custom storage which implements the PreferencesStorage interface
  3. Build prefs screen via MaterialPrefs DSL

If want to use DefaultPreferencesStorage you have to provide initial values through DefaultValuesContainer.

Step 1
Place the MaterialPreferencesView in your layout:

<com.imangazalievm.materialprefs.views.MaterialPreferencesView
        android:id="@+id/prefsView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
XML

Step 2
Create prefs storage and provide initial values:

val defValues = defaultPrefValues {
    "my_string" to "Jhon Doe"
    "my_int" to 99
    "my_long" to 5L
    "my_float" to 2.5f
    "my_boolean" to true
}

val storage = defaultPrefsStorage("my_prefs", defValues)
Kotlin

Step 3
Add pref items via MaterialPrefs DSL:

prefs(prefsView, storage) {
    category("My category") {
         preference {
            title("My pref item")
            icon(R.drawable.my_icon)
            onClick {
                //my action
            }
        }
    }
}   
Kotlin

? Documentation

The library includes 4 modules:

  • core - contains main code: simple prefs, checkbox, switch
  • dialogs - dialogs prefs: single and multiple choice
  • date-time - date and time pickers
  • color-picker - color picker

Three last modules based on Material Dialogs library.

Core

Simple preference:

preference {
    title("Title")
    summary("My description")
    icon(R.drawable.ic_my_icon)
    showArrow(true)
    onClick {
        //my action
    }
}
Kotlin

Switch:

switch("my_key") {
    title("Title")
    summary("My description")
    onChecked { isChecked ->
        //my action
    }
}
Kotlin

Checkbox:

checkbox("my_key") {
    title("Title")
    summary("My description")
    onChecked { isChecked ->
        //my action
    }
}
Kotlin

Label preference:

labelPreference("my_key", String::class) {
    title("Title")
    onClick {
        //my action
    }
}
Kotlin

Dialogs

Single Choice:

listSingleChoice("my_key", String::class) {
    title("Title")
    icon(R.drawable.ic_my_icon)
    showRadioButtons(true)
    items(
        listOf(
            ListItem("ar", "Arabic"),
            ListItem("en", "English"),
            ListItem("ru", "Russian")
        )
    )
}
Kotlin

Multi Choice:

listMultiChoice("my_key", String::class) {
    title("Title")
    allowEmptySelection(false)
    //required
    listValuesSerializer { it.joinToString() }
    //required
    listValuesDeserializer {
        if (it.isNotEmpty()) {
            it.split(",")
                .map { number -> number.trim().toInt() }
        } else emptyList()
    }             
    items(
        listOf(
            ListItem("one", "Item 1"),
            ListItem("two", "Item 2"),
            ListItem("three", "Item 3")
        )
    )
}
Kotlin

Text Input:

textInput("my_key") {
    title("Title")
    icon(R.drawable.ic_username)
    onNewInput { 
        //my action       
    }
}
Kotlin

DateTime

Date picker:

datePicker("my_key") {
    title("Title")
    val formatter = SimpleDateFormat("dd.MM.yyyy ", Locale.US)
    valuePresenter { formatter.format(it) }
    onValueSelected {
        //my action
    }
}
Kotlin

Time picker:

timePicker("my_key") {
    title("Title")
    val formatter = SimpleDateFormat("hh:mm ", Locale.US)
    valuePresenter { formatter.format(it) }
    onValueSelected {
        //my action
    }
}
Kotlin

Date and picker:

dateTimePicker("my_key") {
    title("Title")
    val formatter = SimpleDateFormat("hh:mm dd.MM.yyyy ", Locale.US)
    valuePresenter { formatter.format(it) }
    onValueSelected {
        //my action
    }
}
Kotlin

ColorPicker

colorPicker("my_key") {
    title("Title")
    val colors = intArrayOf(Color.RED, Color.GREEN, Color.BLUE)
    colors(colors)
    onColorSelected {
        //my action
    }
}
Kotlin

Custom preference item

To create custom preference item you have to do 3 steps:

Step 1:
Create preference view class inherited from PreferenceView or BasePreferenceView.

If your view inherited from BasePreferenceView you have to implement createValueView method:

class MyPreferenceView(
    context: Context,
    attrs: AttributeSet? = null,
    themeResId: Int = 0
) : BasePreferenceView(context, attrs, themeResId) {

    override fun createValueView(parent: ViewGroup): View {
        return parent.inflate(R.layout.my_pref_view)
    }

}
Kotlin

Step 2:
Create preference class inherited from Preference or BasePreference and implement 3 methods:

abstract class MyPreference(
    key: String,
    container: PrefsContainer,
    private val appearanceManager: PreferencesAppearance
) : BasePreference<MyPreference, MyPreferenceView, String>(
    container = container,
    key = key,
    appearanceManager = appearanceManager
) {

    override fun createView(): V {
    }

    override fun loadValue(view: V) {
    }
 
    override fun initView(view: V) {
    }

}
Kotlin

Third generic parameter of BasePreference is a type of data, that will be save in the preferences, so it must be one of the following types:

  • String
  • Int
  • Long
  • Float
  • Boolean

Step 3:
Create extension method for MaterialSettings:

fun myPreference(builder: PreferenceBuilder<MyPreference>) {
    MyPreference(container, appearanceManager)
        .apply(builder)
        .also { addPreference(it) }
}
Kotlin

GitHub