hureby / Theme

🎨 An Experimental Theme Engine for Android

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Experimental] Theme

API Releases

image

Theme is an experimental theme engine for Android by retinting views after their creation.

This library is inspired by aesthetic and Cyanea.

WARNING

Theme only works with material-components-android 1.1.0. Any other version doesn't work.

I don't recommend using Theme in the production because the implementation is fragile.

Jetpack Compose supports theming programmatically and is a better alternative(in the future).

Sample App

You can download the APK from Release.

Usage

  1. Install dependency:

    1. Add the JitPack repository to your build file

      allprojects {
          repositories {
              ...
              maven { url 'https://jitpack.io' }
          }
      }
    2. Add the dependency

      Releases

      dependencies {
          implementation 'xyz.aprildown:Theme:0.1.2'
      }
  2. 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 how TypedArray.getResourceId works.
  3. 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>
  4. In your Application:

    Theme.init(
        context = this,
        themeRes = R.style.AppTheme
    ) {
        // Optional. Provide initial colors here.
        // The usage is same as the code below.
    }
  5. 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 a ColorRes. Other variables expect a ColorInt.
    • After editing, you have to recreate activities in the back stack manually.
  6. 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 using DrawerLayout, put it after DrawerLayout is inflated(usually it's after setContentView).

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

  1. Create a ThemeInflationDelegate like AppComponentsDelegate.

  2. 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 like TimePicker.
  • Theme heavily depends on material-components-android 1.1.0 internal resources ID, making it doesn't work with 1.0.0, 1.2.0, or later.

How Theme Works

material-components-android 1.1.0 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

About

🎨 An Experimental Theme Engine for Android

License:Apache License 2.0


Languages

Language:Kotlin 100.0%