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