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
supports material-components-android
1.1.0, 1.2.x, 1.3.0 and 1.4.0. Any other version doesn't work.Install dependency:
Add the JitPack repository to your build file
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
Add the dependency
dependencies {
implementation 'xyz.aprildown:Theme:0.4.0' // for material-components-android 1.4.0
// implementation 'xyz.aprildown:Theme:0.3.1' // for material-components-android 1.3.0
// implementation 'xyz.aprildown:Theme:0.2.0' // for material-components-android 1.2.x
// implementation 'xyz.aprildown:Theme:0.1.4' // for material-components-android 1.1.0
}
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.