Build apps faster with our new App builder! Check it out →

ComposeThemer

Android
⚖️ License Apache License 2.0
Added on 12/4/2024

About

Maven API Kotlin KMP License

ComposeThemer

This is a full compose theme engine that handles applying a theme as well as updating the system ui elements. Extendible and allows to simply apply user selected themes inside your app.

:heavy_check_mark: Features

  • allows to define custom user themes and applies them automatically
  • ability to retrieve all registered themes
  • supports system ui theming (status bar + navigation bar)
  • build on top of MaterialTheme
  • comes with optional 55 build-in themes
  • offers some edgeToEdge helper functions

All features are splitted into separate modules, just include the modules you want to use!

:camera: Screenshots

Demo
DependencyVersionInfos
Compose Multiplatform1.7.0based on compose 1.7.1 and material3 1.3.0

[!NOTE]
This library does not use any experimental compose APIs and therefore should be forward compatible with newer compose versions!

:elephant: Gradle

This library is distributed via maven central.

build.gradle.kts

val composethemer = "<LATEST-VERSION>"

// core module
implementation("io.github.mflisar.composethemer:core:$composethemer")

// extension module
implementation("io.github.mflisar.composethemer:themes:$composethemer")

:zap: Modules

ModuleInfoDescription
corethe core module that provides all theming functions
themesa collection of 55 predefined themes

</> Basic Usage

Inside your application register all available themes (or at least one) like following:

class App : Application() {

    override fun onCreate() {
        super.onCreate()

        // register available themes
        ComposeTheme.register(*ComposeThemes.ALL.toTypedArray())

        // or register some of them
        // ComposeTheme.register(
        //     ThemeAmberBlue.get(),
        //     ThemeAquaBlue.get(),
        //     ThemeBahamaAndTrinidad.get(),
        //     // ...
        // )

        // get a single theme
        // val theme = ThemeAmberBlue.get()

        // or register your own themes...
        // ...
    }
}

Then use the ComposeTheme composable to apply the theme like following:

// simply wrap your composable content inside ComposeTheme as if you would use MaterialTheme directly
val baseTheme = remember { mutableStateOf(ComposeTheme.BaseTheme.System) }
val dynamic = remember { mutableStateOf(false) }
val theme = remember { mutableStateOf(ThemeGreenForest.KEY) } // the key of an registered theme
val state = ComposeTheme.State(baseTheme, dynamic, theme)
ComposeTheme(state = state) {

    // update edgeToEdge to the correct styles with the provided helper functions
    // e.g. like following if the layout has a primary toolbar at top and nothing at bottom
    // TIPP:
    // this functions has an overload that works with SystemBarStyle instead if you want to use that directly
    ComposeTheme.enableEdgeToEdge(
        activity = this,
        statusBarColor = MaterialTheme.colorScheme.primary,
        navigationBarColor = if (landscape) {
            SystemBarStyle.defaultScrim(resources)
        } else MaterialTheme.colorScheme.background,
        isNavigationBarContrastEnforced = landscape
    )

    // content
}
Themes Extension Module
// returns a list of all existing default themes
val themes = ComposeTheme.getRegisteredThemes()

// or get the default themes one by one (all named like Theme*)
val theme = ThemeAmberBlue.get()
// ... there are 56 predefined themes availabe ...
SystemBarStyle functions

I added some extensions to SystemBarStyle.Companion.

// following gives you a fully transparent SystemBarStyle or the default SystemBarStyle for the statusbar or navigationbar
SystemBarStyle.transparent()
SystemBarStyle.statusBar()
SystemBarStyle.navigationBar()
// this gives you the default scrim color that is normally defined privately aand can't be easily accessed
SystemBarStyle.defaultScrim(resource)
Disable the edgeToEdge mode

If desired, you can still use this library without using the edgeToEdge feature.

ComposeTheme(state = state, edgeToEdge = false) {
    // content
}

:pray: Credits

This library contains 54 predefined color schemes inside the themes module. Those are all directly copied from FlexColorScheme - a very useful homepage that allows you to create your own themes and also contains 54 predefined themes already. With the permission of Rydmike I just copied every single predefined theme from his homepage and added it to this library.