Skip to content

AppCompat Compose Theme Adapter

Maven Central

A library that enables reuse of AppCompat XML themes for theming in Jetpack Compose.

The basis of theming in Jetpack Compose is the MaterialTheme composable, where you provide Colors, Shapes and Typography instances containing your styling parameters:

MaterialTheme(
    typography = type,
    colors = colors,
    shapes = shapes
) {
    // Surface, Scaffold, etc
}

AppCompat XML themes allow for similar but coarser theming via XML theme attributes, like so:

<style name="Theme.MyApp" parent="Theme.AppCompat.DayNight">
    <item name="colorPrimary">@color/purple_500</item>
    <item name="colorAccent">@color/green_200</item>
</style>

This library attempts to bridge the gap between AppCompat XML themes, and themes in Jetpack Compose, allowing your composable MaterialTheme to be based on the Activity's XML theme:

AppCompatTheme {
    // MaterialTheme.colors, MaterialTheme.shapes, MaterialTheme.typography
    // will now contain copies of the context's theme
}

This is especially handy when you're migrating an existing app, a fragment (or other UI container) at a time.

Caution

If you are using Material Design Components in your app, you should use the MDC Compose Theme Adapter instead, as it allows much finer-grained reading of your theme.

Customizing the theme

The AppCompatTheme() function will automatically read the host context's AppCompat theme and pass them to MaterialTheme on your behalf, but if you want to customize the generated values, you can do so via the createAppCompatTheme() function:

val context = LocalContext.current
var (colors, type) = context.createAppCompatTheme()

// Modify colors or type as required. Then pass them
// through to MaterialTheme...

MaterialTheme(
    colors = colors,
    typography = type
) {
    // rest of layout
}

Generated theme

Synthesizing a material theme from a Theme.AppCompat theme is not perfect, since Theme.AppCompat does not expose the same level of customization as is available in material theming. Going through the pillars of material theming:

Colors

AppCompat has a limited set of top-level color attributes, which means that AppCompatTheme() has to generate/select alternative colors in certain situations. The mapping is currently:

MaterialTheme color AppCompat attribute
primary colorPrimary
primaryVariant colorPrimaryDark
onPrimary Calculated black/white
secondary colorAccent
secondaryVariant colorAccent
onSecondary Calculated black/white
surface Default
onSurface android:textColorPrimary, else calculated black/white
background android:colorBackground
onBackground android:textColorPrimary, else calculated black/white
error colorError
onError Calculated black/white

Where the table says "calculated black/white", this means either black/white, depending on which provides the greatest contrast against the corresponding background color.

Typography

AppCompat does not provide any semantic text appearances (such as headline6, body1, etc), and instead relies on text appearances for specific widgets or use cases. As such, the only thing we read from an AppCompat theme is the default app:fontFamily or android:fontFamily. For example:

<style name="Theme.MyApp" parent="Theme.AppCompat">
    <item name="fontFamily">@font/my_font</item>
</style>

Compose does not currently support downloadable fonts, so any font referenced from the theme should from your resources. See here for more information.

Shape

AppCompat has no concept of shape theming, therefore we use the default value from MaterialTheme.shapes. If you wish to provide custom values, use the shapes parameter on AppCompatTheme.

Limitations

There are some known limitations with the implementation at the moment:

  • This relies on your Activity/Context theme extending one of the Theme.AppCompat themes.
  • Variable fonts are not supported in Compose yet, meaning that the value of android:fontVariationSettings are currently ignored.
  • You can modify the resulting MaterialTheme in Compose as required, but this only works in Compose. Any changes you make will not be reflected in the Activity theme.

Usage

Maven Central

repositories {
    mavenCentral()
}

dependencies {
    implementation "com.google.accompanist:accompanist-appcompat-theme:<version>"
}

Library Snapshots

Snapshots of the current development version of this library are available, which track the latest commit. See here for more information on how to use them.


Contributions

Please contribute! We will gladly review any pull requests. Make sure to read the Contributing page first though.

License

Copyright 2020 The Android Open Source Project

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.