xref: /aosp_15_r20/external/accompanist/docs/themeadapter-appcompat.md (revision fa44fe6ae8e729aa3cfe5c03eedbbf98fb44e2c6)
1# AppCompat Theme Adapter
2
3[![Maven Central](https://img.shields.io/maven-central/v/com.google.accompanist/accompanist-themeadapter-appcompat)](https://search.maven.org/search?q=g:com.google.accompanist)
4
5!!! warning
6    **This library is deprecated, and the API is no longer maintained.** The original documentation is below.
7
8## Migration
9Recommendation: Use the [Material Theme Builder](https://m3.material.io/theme-builder) tool, or an alternative design tool, to generate a matching XML and Compose theme implementation for your app. See [Migrating XML themes to Compose](https://developer.android.com/jetpack/compose/designsystems/views-to-compose) to learn more.
10
11You can checkout [Material Design 3 in Compose](https://developer.android.com/jetpack/compose/designsystems/material3#material-theming) to learn more about creating and adding theme to your app using Material Theme Builder.
12
13## Original Documenation
14
15A library that enables the reuse of [AppCompat][appcompat] XML themes, for theming in [Jetpack Compose][compose].
16
17The 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:
18
19``` kotlin
20MaterialTheme(
21    typography = type,
22    colors = colors,
23    shapes = shapes
24) {
25    // Surface, Scaffold, etc
26}
27```
28
29[AppCompat][appcompat] XML themes allow for similar but coarser theming via XML theme attributes, like so:
30
31``` xml
32<style name="Theme.MyApp" parent="Theme.AppCompat.DayNight">
33    <item name="colorPrimary">@color/purple_500</item>
34    <item name="colorAccent">@color/green_200</item>
35</style>
36```
37
38This 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:
39
40``` kotlin
41AppCompatTheme {
42    // MaterialTheme.colors, MaterialTheme.shapes, MaterialTheme.typography
43    // will now contain copies of the context's theme
44}
45```
46
47This is especially handy when you're migrating an existing app, a fragment (or other UI container) at a time.
48
49!!! caution
50    If you are using [Material Design Components][mdc] in your app, you should use the
51    [Material Theme Adapter](https://github.com/google/accompanist/tree/main/themeadapter-material) or
52    [Material 3 Theme Adapter](https://github.com/google/accompanist/tree/main/themeadapter-material3)
53    instead, as they allow much finer-grained reading of your theme.
54
55
56### Customizing the theme
57
58The [`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:
59
60``` kotlin
61val context = LocalContext.current
62var (colors, type) = context.createAppCompatTheme()
63
64// Modify colors or type as required. Then pass them
65// through to MaterialTheme...
66
67MaterialTheme(
68    colors = colors,
69    typography = type
70) {
71    // rest of layout
72}
73```
74
75</details>
76
77## Generated theme
78
79Synthesizing a material theme from a `Theme.AppCompat` theme is not perfect, since `Theme.AppCompat`
80does not expose the same level of customization as is available in material theming.
81Going through the pillars of material theming:
82
83### Colors
84
85AppCompat has a limited set of top-level color attributes, which means that [`AppCompatTheme()`][appcompattheme]
86has to generate/select alternative colors in certain situations. The mapping is currently:
87
88| MaterialTheme color | AppCompat attribute                                            |
89|---------------------|-------------------------------------------------------|
90| primary             | `colorPrimary`                                          |
91| primaryVariant      | `colorPrimaryDark`                                      |
92| onPrimary           | Calculated black/white                                |
93| secondary           | `colorAccent`                                           |
94| secondaryVariant    | `colorAccent`                                           |
95| onSecondary         | Calculated black/white                                |
96| surface             | Default                                               |
97| onSurface           | `android:textColorPrimary`, else calculated black/white |
98| background          | `android:colorBackground`                               |
99| onBackground        | `android:textColorPrimary`, else calculated black/white |
100| error               | `colorError`                                            |
101| onError             | Calculated black/white                                |
102
103Where the table says "calculated black/white", this means either black/white, depending on
104which provides the greatest contrast against the corresponding background color.
105
106### Typography
107
108AppCompat does not provide any semantic text appearances (such as headline6, body1, etc), and
109instead relies on text appearances for specific widgets or use cases. As such, the only thing
110we read from an AppCompat theme is the default `app:fontFamily` or `android:fontFamily`.
111For example:
112
113``` xml
114<style name="Theme.MyApp" parent="Theme.AppCompat">
115    <item name="fontFamily">@font/my_font</item>
116</style>
117```
118
119Compose does not currently support downloadable fonts, so any font referenced from the theme
120should from your resources. See [here](https://developer.android.com/guide/topics/resources/font-resource)
121for more information.
122
123### Shape
124
125AppCompat has no concept of shape theming, therefore we use the default value from
126[`MaterialTheme.shapes`][shapes]. If you wish to provide custom values, use the `shapes` parameter on `AppCompatTheme`.
127
128## Limitations
129
130There are some known limitations with the implementation at the moment:
131
132* This relies on your `Activity`/`Context` theme extending one of the `Theme.AppCompat` themes.
133* Variable fonts are not supported in Compose yet, meaning that the value of `android:fontVariationSettings` are currently ignored.
134* 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.
135
136---
137
138## Usage
139
140[![Maven Central](https://img.shields.io/maven-central/v/com.google.accompanist/accompanist-themeadapter-appcompat)](https://search.maven.org/search?q=g:com.google.accompanist)
141
142``` groovy
143repositories {
144    mavenCentral()
145}
146
147dependencies {
148    implementation "com.google.accompanist:accompanist-themeadapter-appcompat:<version>"
149}
150```
151
152### Library Snapshots
153
154Snapshots 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.
155
156---
157
158## Contributions
159
160Please contribute! We will gladly review any pull requests.
161Make sure to read the [Contributing](../contributing) page first though.
162
163## License
164
165```
166Copyright 2022 The Android Open Source Project
167
168Licensed under the Apache License, Version 2.0 (the "License");
169you may not use this file except in compliance with the License.
170You may obtain a copy of the License at
171
172    https://www.apache.org/licenses/LICENSE-2.0
173
174Unless required by applicable law or agreed to in writing, software
175distributed under the License is distributed on an "AS IS" BASIS,
176WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
177See the License for the specific language governing permissions and
178limitations under the License.
179```
180
181[compose]: https://developer.android.com/jetpack/compose
182[mdc]: https://github.com/material-components/material-components-android
183[appcompat]: https://developer.android.com/jetpack/androidx/releases/appcompat
184[appcompattheme]: ../api/themeadapter-appcompat/com.google.accompanist.themeadapter.appcompat/-app-compat-theme.html
185[createappcompattheme]: ../api/themeadapter-appcompat/com.google.accompanist.themeadapter.appcompat/create-app-compat-theme.html
186[materialtheme]: https://developer.android.com/reference/kotlin/androidx/compose/material/MaterialTheme
187[colors]: https://developer.android.com/reference/kotlin/androidx/compose/material/Colors
188[typography]: https://developer.android.com/reference/kotlin/androidx/compose/material/Typography
189[shapes]: https://developer.android.com/reference/kotlin/androidx/compose/material/Shapes
190