Theme
is an experimental theme engine for Android by retinting views after their creation.
This library is inspired by aesthetic and Cyanea.
Theme
is a companion of material-components-android, so it requires you to adopt material-components-android
in your project.Theme
only supports material-components-android
1.4.0. Any other version doesn't work.Install dependency:
Define six theme colors:
<resources>
<color name="colorPrimary">#008577</color>
<color name="colorPrimaryVariant">#00574B</color>
<color name="colorOnPrimary">#FFFFFF</color>
<color name="colorSecondary">#D81B60</color>
<color name="colorSecondaryVariant">#A00037</color>
<color name="colorOnSecondary">#FFFFFF</color>
</resources>
#RRGGBB
. Color references won't work because of how TypedArray.getResourceId
works.Add an attribute to your root theme:
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
...
<!-- Add this line -->
<item name="viewInflaterClass">xyz.aprildown.theme.ThemeViewInflater</item>
</style>
In your Application:
Theme.init(
context = this,
themeRes = R.style.AppTheme
) {
// Optional. Provide initial colors here.
// The usage is same as the code below.
}
Change colors:
Theme.edit(this) {
colorPrimaryRes = R.color.md_amber_500
colorPrimaryVariantRes = R.color.md_amber_800
colorOnPrimary = on(colorPrimary)
colorSecondaryRes = R.color.md_blue_500
colorSecondaryVariantRes = R.color.md_blue_800
colorOnSecondary = on(colorSecondary)
colorStatusBar = colorPrimaryVariant
}
Res
expect a ColorRes
. Other variables expect a ColorInt
.[Optional] Use colors at runtime.
Theme.get().colorPrimary
Theme.tintSystemUi(activity)
onCreate
, but if you're using DrawerLayout
, put it after DrawerLayout
is inflated(usually it's after setContentView
).This's useful when you show a MaterialDatePicker
because Theme
messes up its colors.
button.setOnClickListener {
Theme.get().enabled = false
MaterialDatePicker.Builder.datePicker()
.build()
.apply {
addOnDismissListener {
Theme.get().enabled = true
}
}
.show(childFragmentManager, null)
}
ThemeInflationDelegate
like AppComponentsDelegate.Add it after Theme
's initialization:
Theme.init(...)
Theme.installDelegates(AppComponentsDelegate())
Toolbar
according to the docs, or the tint doesn't work.Theme
doesn't use any reflection, so it's hard to tint widgets like TimePicker
.Theme
Worksmaterial-components-android
makes setting attributes programmatically very easy. ThemeViewInflater extends MaterialComponentsViewInflater and does all retint work. Classes named ***Tint
resolves color attributes from AttributeSet
and applies new color.