xref: /aosp_15_r20/external/accompanist/docs/appcompat-theme.md (revision fa44fe6ae8e729aa3cfe5c03eedbbf98fb44e2c6)
1*fa44fe6aSInna Palant# AppCompat Compose Theme Adapter
2*fa44fe6aSInna Palant
3*fa44fe6aSInna Palant[![Maven Central](https://img.shields.io/maven-central/v/com.google.accompanist/accompanist-appcompat-theme)](https://search.maven.org/search?q=g:com.google.accompanist)
4*fa44fe6aSInna Palant
5*fa44fe6aSInna Palant!!! warning
6*fa44fe6aSInna Palant	**This library is deprecated in favor of the new [`themeadapter-appcompat`][themeadapterappcompatlib] artifact.** The migration guide and original documentation is below.
7*fa44fe6aSInna Palant
8*fa44fe6aSInna Palant## Migration
9*fa44fe6aSInna Palant
10*fa44fe6aSInna PalantAccompanist AppCompat Theme Adapter has moved from the [`appcompat-theme`][appcompatthemelib] artifact to the [`themeadapter-appcompat`][themeadapterappcompatlib] artifact.
11*fa44fe6aSInna PalantThe implementation is identical but the dependency and import package have changed.
12*fa44fe6aSInna Palant
13*fa44fe6aSInna Palant### Migration steps
14*fa44fe6aSInna Palant
15*fa44fe6aSInna Palant1. Change the dependency from `com.google.accompanist:accompanist-appcompat-theme:<version>` to `com.google.accompanist:accompanist-themeadapter-appcompat:<version>`
16*fa44fe6aSInna Palant2. Change any `com.google.accompanist.appcompattheme.*` imports to `com.google.accompanist.themeadapter.appcompat.*`
17*fa44fe6aSInna Palant
18*fa44fe6aSInna Palant## Original Docs
19*fa44fe6aSInna Palant
20*fa44fe6aSInna PalantA library that enables reuse of [AppCompat][appcompat] XML themes for theming in [Jetpack Compose][compose].
21*fa44fe6aSInna Palant
22*fa44fe6aSInna PalantThe basis of theming in [Jetpack Compose][compose] is the [`MaterialTheme`][materialtheme] composable, where you provide [`Colors`][colors], [`Shapes`][shapes] and [`Typography`][typography] instances containing your styling parameters:
23*fa44fe6aSInna Palant
24*fa44fe6aSInna Palant``` kotlin
25*fa44fe6aSInna PalantMaterialTheme(
26*fa44fe6aSInna Palant    typography = type,
27*fa44fe6aSInna Palant    colors = colors,
28*fa44fe6aSInna Palant    shapes = shapes
29*fa44fe6aSInna Palant) {
30*fa44fe6aSInna Palant    // Surface, Scaffold, etc
31*fa44fe6aSInna Palant}
32*fa44fe6aSInna Palant```
33*fa44fe6aSInna Palant
34*fa44fe6aSInna Palant[AppCompat][appcompat] XML themes allow for similar but coarser theming via XML theme attributes, like so:
35*fa44fe6aSInna Palant
36*fa44fe6aSInna Palant``` xml
37*fa44fe6aSInna Palant<style name="Theme.MyApp" parent="Theme.AppCompat.DayNight">
38*fa44fe6aSInna Palant    <item name="colorPrimary">@color/purple_500</item>
39*fa44fe6aSInna Palant    <item name="colorAccent">@color/green_200</item>
40*fa44fe6aSInna Palant</style>
41*fa44fe6aSInna Palant```
42*fa44fe6aSInna Palant
43*fa44fe6aSInna PalantThis library attempts to bridge the gap between [AppCompat][appcompat] XML themes, and themes in [Jetpack Compose][compose], allowing your composable [`MaterialTheme`][materialtheme] to be based on the `Activity`'s XML theme:
44*fa44fe6aSInna Palant
45*fa44fe6aSInna Palant``` kotlin
46*fa44fe6aSInna PalantAppCompatTheme {
47*fa44fe6aSInna Palant    // MaterialTheme.colors, MaterialTheme.shapes, MaterialTheme.typography
48*fa44fe6aSInna Palant    // will now contain copies of the context's theme
49*fa44fe6aSInna Palant}
50*fa44fe6aSInna Palant```
51*fa44fe6aSInna Palant
52*fa44fe6aSInna PalantThis is especially handy when you're migrating an existing app, a fragment (or other UI container) at a time.
53*fa44fe6aSInna Palant
54*fa44fe6aSInna Palant!!! caution
55*fa44fe6aSInna Palant    If you are using [Material Design Components](https://material.io/develop/android/) in your app, you should use the
56*fa44fe6aSInna Palant    [MDC Compose Theme Adapter](https://github.com/material-components/material-components-android-compose-theme-adapter)
57*fa44fe6aSInna Palant    instead, as it allows much finer-grained reading of your theme.
58*fa44fe6aSInna Palant
59*fa44fe6aSInna Palant
60*fa44fe6aSInna Palant### Customizing the theme
61*fa44fe6aSInna Palant
62*fa44fe6aSInna PalantThe [`AppCompatTheme()`][appcompattheme] function will automatically read the host context's AppCompat theme and pass them to [`MaterialTheme`][materialtheme] on your behalf, but if you want to customize the generated values, you can do so via the [`createAppCompatTheme()`][createappcompattheme] function:
63*fa44fe6aSInna Palant
64*fa44fe6aSInna Palant``` kotlin
65*fa44fe6aSInna Palantval context = LocalContext.current
66*fa44fe6aSInna Palantvar (colors, type) = context.createAppCompatTheme()
67*fa44fe6aSInna Palant
68*fa44fe6aSInna Palant// Modify colors or type as required. Then pass them
69*fa44fe6aSInna Palant// through to MaterialTheme...
70*fa44fe6aSInna Palant
71*fa44fe6aSInna PalantMaterialTheme(
72*fa44fe6aSInna Palant    colors = colors,
73*fa44fe6aSInna Palant    typography = type
74*fa44fe6aSInna Palant) {
75*fa44fe6aSInna Palant    // rest of layout
76*fa44fe6aSInna Palant}
77*fa44fe6aSInna Palant```
78*fa44fe6aSInna Palant
79*fa44fe6aSInna Palant</details>
80*fa44fe6aSInna Palant
81*fa44fe6aSInna Palant## Generated theme
82*fa44fe6aSInna Palant
83*fa44fe6aSInna PalantSynthesizing a material theme from a `Theme.AppCompat` theme is not perfect, since `Theme.AppCompat`
84*fa44fe6aSInna Palantdoes not expose the same level of customization as is available in material theming.
85*fa44fe6aSInna PalantGoing through the pillars of material theming:
86*fa44fe6aSInna Palant
87*fa44fe6aSInna Palant### Colors
88*fa44fe6aSInna Palant
89*fa44fe6aSInna PalantAppCompat has a limited set of top-level color attributes, which means that [`AppCompatTheme()`][appcompattheme]
90*fa44fe6aSInna Palanthas to generate/select alternative colors in certain situations. The mapping is currently:
91*fa44fe6aSInna Palant
92*fa44fe6aSInna Palant| MaterialTheme color | AppCompat attribute                                            |
93*fa44fe6aSInna Palant|---------------------|-------------------------------------------------------|
94*fa44fe6aSInna Palant| primary             | `colorPrimary`                                          |
95*fa44fe6aSInna Palant| primaryVariant      | `colorPrimaryDark`                                      |
96*fa44fe6aSInna Palant| onPrimary           | Calculated black/white                                |
97*fa44fe6aSInna Palant| secondary           | `colorAccent`                                           |
98*fa44fe6aSInna Palant| secondaryVariant    | `colorAccent`                                           |
99*fa44fe6aSInna Palant| onSecondary         | Calculated black/white                                |
100*fa44fe6aSInna Palant| surface             | Default                                               |
101*fa44fe6aSInna Palant| onSurface           | `android:textColorPrimary`, else calculated black/white |
102*fa44fe6aSInna Palant| background          | `android:colorBackground`                               |
103*fa44fe6aSInna Palant| onBackground        | `android:textColorPrimary`, else calculated black/white |
104*fa44fe6aSInna Palant| error               | `colorError`                                            |
105*fa44fe6aSInna Palant| onError             | Calculated black/white                                |
106*fa44fe6aSInna Palant
107*fa44fe6aSInna PalantWhere the table says "calculated black/white", this means either black/white, depending on
108*fa44fe6aSInna Palantwhich provides the greatest contrast against the corresponding background color.
109*fa44fe6aSInna Palant
110*fa44fe6aSInna Palant### Typography
111*fa44fe6aSInna Palant
112*fa44fe6aSInna PalantAppCompat does not provide any semantic text appearances (such as headline6, body1, etc), and
113*fa44fe6aSInna Palantinstead relies on text appearances for specific widgets or use cases. As such, the only thing
114*fa44fe6aSInna Palantwe read from an AppCompat theme is the default `app:fontFamily` or `android:fontFamily`.
115*fa44fe6aSInna PalantFor example:
116*fa44fe6aSInna Palant
117*fa44fe6aSInna Palant``` xml
118*fa44fe6aSInna Palant<style name="Theme.MyApp" parent="Theme.AppCompat">
119*fa44fe6aSInna Palant    <item name="fontFamily">@font/my_font</item>
120*fa44fe6aSInna Palant</style>
121*fa44fe6aSInna Palant```
122*fa44fe6aSInna Palant
123*fa44fe6aSInna PalantCompose does not currently support downloadable fonts, so any font referenced from the theme
124*fa44fe6aSInna Palantshould from your resources. See [here](https://developer.android.com/guide/topics/resources/font-resource)
125*fa44fe6aSInna Palantfor more information.
126*fa44fe6aSInna Palant
127*fa44fe6aSInna Palant### Shape
128*fa44fe6aSInna Palant
129*fa44fe6aSInna PalantAppCompat has no concept of shape theming, therefore we use the default value from
130*fa44fe6aSInna Palant[`MaterialTheme.shapes`][shapes]. If you wish to provide custom values, use the `shapes` parameter on `AppCompatTheme`.
131*fa44fe6aSInna Palant
132*fa44fe6aSInna Palant## Limitations
133*fa44fe6aSInna Palant
134*fa44fe6aSInna PalantThere are some known limitations with the implementation at the moment:
135*fa44fe6aSInna Palant
136*fa44fe6aSInna Palant* This relies on your `Activity`/`Context` theme extending one of the `Theme.AppCompat` themes.
137*fa44fe6aSInna Palant* Variable fonts are not supported in Compose yet, meaning that the value of `android:fontVariationSettings` are currently ignored.
138*fa44fe6aSInna Palant* 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.
139*fa44fe6aSInna Palant
140*fa44fe6aSInna Palant---
141*fa44fe6aSInna Palant
142*fa44fe6aSInna Palant## Usage
143*fa44fe6aSInna Palant
144*fa44fe6aSInna Palant[![Maven Central](https://img.shields.io/maven-central/v/com.google.accompanist/accompanist-appcompat-theme)](https://search.maven.org/search?q=g:com.google.accompanist)
145*fa44fe6aSInna Palant
146*fa44fe6aSInna Palant``` groovy
147*fa44fe6aSInna Palantrepositories {
148*fa44fe6aSInna Palant    mavenCentral()
149*fa44fe6aSInna Palant}
150*fa44fe6aSInna Palant
151*fa44fe6aSInna Palantdependencies {
152*fa44fe6aSInna Palant    implementation "com.google.accompanist:accompanist-appcompat-theme:<version>"
153*fa44fe6aSInna Palant}
154*fa44fe6aSInna Palant```
155*fa44fe6aSInna Palant
156*fa44fe6aSInna Palant### Library Snapshots
157*fa44fe6aSInna Palant
158*fa44fe6aSInna PalantSnapshots of the current development version of this library are available, which track the latest commit. See [here](../using-snapshot-version) for more information on how to use them.
159*fa44fe6aSInna Palant
160*fa44fe6aSInna Palant---
161*fa44fe6aSInna Palant
162*fa44fe6aSInna Palant## Contributions
163*fa44fe6aSInna Palant
164*fa44fe6aSInna PalantPlease contribute! We will gladly review any pull requests.
165*fa44fe6aSInna PalantMake sure to read the [Contributing](../contributing) page first though.
166*fa44fe6aSInna Palant
167*fa44fe6aSInna Palant## License
168*fa44fe6aSInna Palant
169*fa44fe6aSInna Palant```
170*fa44fe6aSInna PalantCopyright 2020 The Android Open Source Project
171*fa44fe6aSInna Palant
172*fa44fe6aSInna PalantLicensed under the Apache License, Version 2.0 (the "License");
173*fa44fe6aSInna Palantyou may not use this file except in compliance with the License.
174*fa44fe6aSInna PalantYou may obtain a copy of the License at
175*fa44fe6aSInna Palant
176*fa44fe6aSInna Palant    https://www.apache.org/licenses/LICENSE-2.0
177*fa44fe6aSInna Palant
178*fa44fe6aSInna PalantUnless required by applicable law or agreed to in writing, software
179*fa44fe6aSInna Palantdistributed under the License is distributed on an "AS IS" BASIS,
180*fa44fe6aSInna PalantWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
181*fa44fe6aSInna PalantSee the License for the specific language governing permissions and
182*fa44fe6aSInna Palantlimitations under the License.
183*fa44fe6aSInna Palant```
184*fa44fe6aSInna Palant
185*fa44fe6aSInna Palant [appcompatthemelib]: ../appcompat-theme
186*fa44fe6aSInna Palant [themeadapterappcompatlib]: ../themeadapter-appcompat
187*fa44fe6aSInna Palant [compose]: https://developer.android.com/jetpack/compose
188*fa44fe6aSInna Palant [appcompat]: https://developer.android.com/jetpack/androidx/releases/appcompat
189*fa44fe6aSInna Palant [appcompattheme]: ../api/appcompat-theme/appcompat-theme/com.google.accompanist.appcompattheme/-app-compat-theme.html
190*fa44fe6aSInna Palant [createappcompattheme]: ../api/appcompat-theme/appcompat-theme/com.google.accompanist.appcompattheme/create-app-compat-theme.html
191*fa44fe6aSInna Palant [materialtheme]: https://developer.android.com/reference/kotlin/androidx/compose/material/MaterialTheme
192*fa44fe6aSInna Palant [shapes]: https://developer.android.com/reference/kotlin/androidx/compose/material/Shapes
193*fa44fe6aSInna Palant [colors]: https://developer.android.com/reference/kotlin/androidx/compose/material/Colors
194*fa44fe6aSInna Palant [typography]: https://developer.android.com/reference/kotlin/androidx/compose/material/Typography