Theme
Theme copied to clipboard
🎨 An Experimental Theme Engine for Android
[Experimental] Theme

Theme
is an experimental theme engine for Android by retinting views after their creation.
This library is inspired by aesthetic and Cyanea.
WARNING
-
Theme
is a companion of material-components-android, so it requires you to adoptmaterial-components-android
in your project. - Currently,
Theme
supportsmaterial-components-android
1.1.0, 1.2.x, 1.3.0 and 1.4.0. Any other version doesn't work. - Because the implementation is fragile, think twice, and do some investigation before using this library.
- Jetpack Compose supports theming programmatically and is a better alternative(in the future).
Sample App
Usage
-
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>
- The color resources name must be identical to the names above.
-
Color values must be formatted as
#RRGGBB
. Color references won't work because of howTypedArray.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 }
- Variables ending with
Res
expect aColorRes
. Other variables expect aColorInt
. - After editing, you have to recreate activities in the back stack manually.
- Variables ending with
-
[Optional] Use colors at runtime.
Theme.get().colorPrimary
More Settings
Tint Status Bar and Navigation Bar
Theme.tintSystemUi(activity)
- Put it in activity's
onCreate
, but if you're usingDrawerLayout
, put it afterDrawerLayout
is inflated(usually it's aftersetContentView
).
Disable Theme
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)
}
Support Custom Views
-
Create a
ThemeInflationDelegate
like AppComponentsDelegate. -
Add it after
Theme
's initialization:Theme.init(...) Theme.installDelegates(AppComponentsDelegate())
Limitation
- Style
Toolbar
according to the docs, or the tint doesn't work. -
Theme
doesn't use any reflection, so it's hard to tint widgets likeTimePicker
.
How Theme
Works
material-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.
License
Apache License 2.0