xref: /aosp_15_r20/external/accompanist/docs/insets.md (revision fa44fe6ae8e729aa3cfe5c03eedbbf98fb44e2c6)
1*fa44fe6aSInna Palant# Insets for Jetpack Compose
2*fa44fe6aSInna Palant
3*fa44fe6aSInna Palant[![Maven Central](https://img.shields.io/maven-central/v/com.google.accompanist/accompanist-insets)](https://search.maven.org/search?q=g:com.google.accompanist)
4*fa44fe6aSInna Palant
5*fa44fe6aSInna Palant!!! warning
6*fa44fe6aSInna Palant    **This library is deprecated, with official insets support in androidx.compose.foundation.** The migration guide and original documentation is below.
7*fa44fe6aSInna Palant
8*fa44fe6aSInna Palant## Migration
9*fa44fe6aSInna Palant
10*fa44fe6aSInna PalantThe official `androidx.compose.foundation` insets support is very similar to accompanist/insets, with a few changes.
11*fa44fe6aSInna Palant
12*fa44fe6aSInna Palant`androidx.compose.foundation` also does not disable window decor fitting, so you still need to call [`WindowCompat.setDecorFitsSystemWindows(window, false)`](https://developer.android.com/reference/androidx/core/view/WindowCompat#setDecorFitsSystemWindows(android.view.Window,%20boolean)) from your Activity.
13*fa44fe6aSInna PalantYou also still need to set the system bar backgrounds to be transparent, which can be done with our [System UI Controller](../systemuicontroller) library.
14*fa44fe6aSInna Palant
15*fa44fe6aSInna PalantIf you are using insets for IME support, you also still need to ensure that the activity's `windowSoftInputMode` is set to `adjustResize`:
16*fa44fe6aSInna Palant
17*fa44fe6aSInna Palant```xml
18*fa44fe6aSInna Palant<activity
19*fa44fe6aSInna Palant      android:name=".MyActivity"
20*fa44fe6aSInna Palant      android:windowSoftInputMode="adjustResize">
21*fa44fe6aSInna Palant</activity>
22*fa44fe6aSInna Palant```
23*fa44fe6aSInna Palant
24*fa44fe6aSInna Palant## Migration steps:
25*fa44fe6aSInna Palant
26*fa44fe6aSInna Palant1. Remove `ProvideWindowInsets` (there is no equivalent in `androidx.compose.foundation`)
27*fa44fe6aSInna Palant1. Remove `ViewWindowInsetObserver` (there is no equivalent in `androidx.compose.foundation`)
28*fa44fe6aSInna Palant1. Replace padding modifiers with `androidx.compose.foundation` equivalents. If using `additionalPadding` or only applying the insets to certain sides, use the corresponding [`WindowInsets.add`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/layout/package-summary#(androidx.compose.foundation.layout.WindowInsets).add(androidx.compose.foundation.layout.WindowInsets)) and [`WindowInsets.only`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/layout/package-summary#(androidx.compose.foundation.layout.WindowInsets).only(androidx.compose.foundation.layout.WindowInsetsSides)) extensions.
29*fa44fe6aSInna Palant1. Replace `rememberInsetsPaddingValues` with the equivalent `WindowInsets.asPaddingValues`.
30*fa44fe6aSInna Palant1. Replace direct calculations from `LocalWindowInsets.current` with calculations on `WindowInsets`.
31*fa44fe6aSInna Palant1. Continue using the non-deprecated [`insets-ui`](#inset-aware-layouts-insets-ui) for now.
32*fa44fe6aSInna Palant
33*fa44fe6aSInna PalantFor reference, consult the [Migration table](#migration-table) below.
34*fa44fe6aSInna Palant
35*fa44fe6aSInna Palant## Inset consumption
36*fa44fe6aSInna Palant
37*fa44fe6aSInna PalantThe biggest behavioral change between `accompanist/insets` and `androidx.compose.foundation` is in the consumption behavior of padding modifiers.
38*fa44fe6aSInna Palant
39*fa44fe6aSInna PalantIn `accompanist/insets`, the padding modifiers always padded the full size of the specified inset types, which led to some unintuitive duplicate padding when nesting modifiers.
40*fa44fe6aSInna Palant
41*fa44fe6aSInna PalantFor example, let’s look at what happens when we have nested boxes, where the outer one has Modifier.systemBarsPadding() applied, and the inner has Modifier.imePadding():
42*fa44fe6aSInna Palant
43*fa44fe6aSInna Palant```kotlin
44*fa44fe6aSInna PalantBox(Modifier.systemBarsPadding()) {
45*fa44fe6aSInna Palant    Box(Modifier.imePadding()) {
46*fa44fe6aSInna Palant        // content
47*fa44fe6aSInna Palant    }
48*fa44fe6aSInna Palant}
49*fa44fe6aSInna Palant```
50*fa44fe6aSInna Palant
51*fa44fe6aSInna PalantLet’s assume that the bottom system bar padding is `30dp`, to account for the navigation bar padding, and let’s assume that when the IME is visible, the height of the IME is `150dp`.
52*fa44fe6aSInna Palant
53*fa44fe6aSInna PalantWhen the IME is closed, the outer box will apply the bottom `30dp` as padding, and the inner box will apply zero additional padding, since the IME isn’t visible.
54*fa44fe6aSInna Palant
55*fa44fe6aSInna PalantWhen the IME opens, the outer box will continue to apply the bottom `30dp` as the system bar padding, and the inner box will now apply `150dp` bottom padding, since that is the full height of the IME.
56*fa44fe6aSInna Palant
57*fa44fe6aSInna PalantThis results in a total padding of `180dp` applied to the content, which double pads the bottom navigation bar padding.
58*fa44fe6aSInna PalantThe solutions to this issue were using `derivedWindowInsetsTypeOf`, built-in derived types like `Modifier.navigationBarsWithImePadding()`, or performing calculations manually to apply the remaining padding.
59*fa44fe6aSInna Palant
60*fa44fe6aSInna PalantIn `androidx.compose.foundation`, when the IME is open, the outer box still apply the bottom `30dp`, but the inner box will only apply the remaining `120dp` needed to have the content be padded a total of `150dp` to match the height of the IME.
61*fa44fe6aSInna Palant
62*fa44fe6aSInna PalantThis behavior can be influenced further in `androidx.compose.foundation` with [`Modifier.consumedWindowInsets()`](https://developer.android.com/reference/kotlin/androidx/compose/ui/Modifier#(androidx.compose.ui.Modifier).consumedWindowInsets(androidx.compose.foundation.layout.WindowInsets))
63*fa44fe6aSInna Palant
64*fa44fe6aSInna PalantAs a result, the equivalent of `Modifier.navigationBarsWithImePadding()` is simply `Modifier.navigationBarsPadding().imePadding()`.
65*fa44fe6aSInna Palant
66*fa44fe6aSInna Palant## Migration table:
67*fa44fe6aSInna Palant
68*fa44fe6aSInna Palant| accompanist/insets                                                                                                                | androidx.compose.foundation                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
69*fa44fe6aSInna Palant|-----------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
70*fa44fe6aSInna Palant| `ProvideWindowInsets`                                                                                                             | (remove)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
71*fa44fe6aSInna Palant| `Modifier.systemBarsPadding()`                                                                                                    | [`Modifier.systemBarsPadding()`](https://developer.android.com/reference/kotlin/androidx/compose/ui/Modifier#(androidx.compose.ui.Modifier).systemBarsPadding())                                                                                                                                                                                                                                                                                                                                        |
72*fa44fe6aSInna Palant| `Modifier.systemBarsPadding(bottom = false)`                                                                                      | [`Modifier.windowInsetsPadding(WindowInsets.systemBars.only(WindowInsetsSides.Horizontal + WindowInsetsSides.Top))`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/layout/package-summary#(androidx.compose.ui.Modifier).windowInsetsPadding(androidx.compose.foundation.layout.WindowInsets))                                                                                                                                                                             |
73*fa44fe6aSInna Palant| `Modifier.statusBarsPadding()`                                                                                                    | [`Modifier.statusBarsPadding()`](https://developer.android.com/reference/kotlin/androidx/compose/ui/Modifier#(androidx.compose.ui.Modifier).statusBarsPadding())                                                                                                                                                                                                                                                                                                                                        |
74*fa44fe6aSInna Palant| `Modifier.navigationBarsPadding()`                                                                                                | [`Modifier.navigationBarsPadding()`](https://developer.android.com/reference/kotlin/androidx/compose/ui/Modifier#(androidx.compose.ui.Modifier).navigationBarsPadding())                                                                                                                                                                                                                                                                                                                                |
75*fa44fe6aSInna Palant| `Modifier.imePadding()`                                                                                                           | [`Modifier.imePadding()`](https://developer.android.com/reference/kotlin/androidx/compose/ui/Modifier#(androidx.compose.ui.Modifier).imePadding())                                                                                                                                                                                                                                                                                                                                                      |
76*fa44fe6aSInna Palant| `Modifier.cutoutPadding()`                                                                                                        | [`Modifier.displayCutoutPadding()`](https://developer.android.com/reference/kotlin/androidx/compose/ui/Modifier#(androidx.compose.ui.Modifier).displayCutoutPadding())                                                                                                                                                                                                                                                                                                                                  |
77*fa44fe6aSInna Palant| `Modifier.navigationBarsWithImePadding()`                                                                                         | [`Modifier.navigationBarsPadding().imePadding()`](https://developer.android.com/reference/kotlin/androidx/compose/ui/Modifier#(androidx.compose.ui.Modifier).imePadding())                                                                                                                                                                                                                                                                                                                              |
78*fa44fe6aSInna Palant| `Modifier.statusBarsHeight()`                                                                                                     | [`Modifier.windowInsetsTopHeight(WindowInsets.statusBars)`](https://developer.android.com/reference/kotlin/androidx/compose/ui/Modifier#(androidx.compose.ui.Modifier).windowInsetsTopHeight(androidx.compose.foundation.layout.WindowInsets))                                                                                                                                                                                                                                                          |
79*fa44fe6aSInna Palant| `Modifier.navigationBarsHeight()`                                                                                                 | [`Modifier.windowInsetsBottomHeight(WindowInsets.navigationBars)`](https://developer.android.com/reference/kotlin/androidx/compose/ui/Modifier#(androidx.compose.ui.Modifier).windowInsetsBottomHeight(androidx.compose.foundation.layout.WindowInsets))                                                                                                                                                                                                                                                |
80*fa44fe6aSInna Palant| `Modifier.navigationBarsWidth()`                                                                                                  | [`Modifier.windowInsetsStartWidth(WindowInsets.navigationBars)`](https://developer.android.com/reference/kotlin/androidx/compose/ui/Modifier#(androidx.compose.ui.Modifier).windowInsetsStartWidth(androidx.compose.foundation.layout.WindowInsets)) / [`Modifier.windowInsetsEndWidth(WindowInsets.navigationBars)`](https://developer.android.com/reference/kotlin/androidx/compose/ui/Modifier#(androidx.compose.ui.Modifier).windowInsetsEndWidth(androidx.compose.foundation.layout.WindowInsets)) |
81*fa44fe6aSInna Palant| `rememberInsetsPaddingValues(insets = LocalWindowInsets.current.statusBars, applyStart = true, applyTop = true, applyEnd = true)` | [`WindowInsets.statusBars.only(WindowInsetsSides.Horizontal + WindowInsetsSides.Top).asPaddingValues()`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/layout/package-summary#(androidx.compose.foundation.layout.WindowInsets).asPaddingValues())                                                                                                                                                                                                                         |
82*fa44fe6aSInna Palant| `derivedWindowInsetsTypeOf`                                                                                                       | [`WindowInsets.union(windowInsets: WindowInsets)`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/layout/package-summary#(androidx.compose.foundation.layout.WindowInsets).union(androidx.compose.foundation.layout.WindowInsets))                                                                                                                                                                                                                                          |
83*fa44fe6aSInna Palant| `LocalWindowInsets.current.navigationBars`                                                                                        | [`WindowInsets.navigationBars`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/layout/package-summary#(androidx.compose.foundation.layout.WindowInsets.Companion).navigationBars())                                                                                                                                                                                                                                                                                         |
84*fa44fe6aSInna Palant| `LocalWindowInsets.current.statusBars`                                                                                            | [`WindowInsets.statusBars`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/layout/package-summary#(androidx.compose.foundation.layout.WindowInsets.Companion).statusBars())                                                                                                                                                                                                                                                                                                 |
85*fa44fe6aSInna Palant| `LocalWindowInsets.current.ime`                                                                                                   | [`WindowInsets.ime`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/layout/package-summary#(androidx.compose.foundation.layout.WindowInsets.Companion).ime())                                                                                                                                                                                                                                                                                                               |
86*fa44fe6aSInna Palant| `LocalWindowInsets.current.systemGestures`                                                                                        | [`WindowInsets.systemGestures`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/layout/package-summary#(androidx.compose.foundation.layout.WindowInsets.Companion).systemGestures())                                                                                                                                                                                                                                                                                         |
87*fa44fe6aSInna Palant| `LocalWindowInsets.current.systemBars`                                                                                            | [`WindowInsets.systemBars`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/layout/package-summary#(androidx.compose.foundation.layout.WindowInsets.Companion).systemBars())                                                                                                                                                                                                                                                                                                 |
88*fa44fe6aSInna Palant| `LocalWindowInsets.current.displayCutout`                                                                                         | [`WindowInsets.displayCutout`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/layout/package-summary#(androidx.compose.foundation.layout.WindowInsets.Companion).displayCutout())                                                                                                                                                                                                                                                                                           |
89*fa44fe6aSInna Palant| `LocalWindowInsets.current.ime.bottom`                                                                                            | [`WindowInsets.ime.getBottom(LocalDensity.current)`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/layout/WindowInsets#getBottom(androidx.compose.ui.unit.Density))                                                                                                                                                                                                                                                                                                        |
90*fa44fe6aSInna Palant| `WindowInsets.Type.isVisible`                                                                                                     | [`WindowInsets.isImeVisible`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/layout/package-summary#(androidx.compose.foundation.layout.WindowInsets.Companion).isImeVisible()), etc.                                                                                                                                                                                                                                                                                       |
91*fa44fe6aSInna Palant| `WindowInsets.Type.animationInProgress`                                                                                           | [Bug: 217770337](https://issuetracker.google.com/issues/217770337)                                                                                                                                                                                                                                                                                                                                                                                                                                      |
92*fa44fe6aSInna Palant| `WindowInsets.Type.animationFraction`                                                                                             | [Bug: 217770337](https://issuetracker.google.com/issues/217770337)                                                                                                                                                                                                                                                                                                                                                                                                                                      |
93*fa44fe6aSInna Palant| `WindowInsets.Type.layoutInsets`                                                                                                  | [Bug: 217770337](https://issuetracker.google.com/issues/217770337)                                                                                                                                                                                                                                                                                                                                                                                                                                      |
94*fa44fe6aSInna Palant| `WindowInsets.Type.animatedInsets`                                                                                                | [Bug: 217770337](https://issuetracker.google.com/issues/217770337)                                                                                                                                                                                                                                                                                                                                                                                                                                      |
95*fa44fe6aSInna Palant| `rememberImeNestedScrollConnection()`                                                                                             | [`Modifier.imeNestedScroll()`](https://developer.android.com/reference/kotlin/androidx/compose/ui/Modifier#(androidx.compose.ui.Modifier).imeNestedScroll())                                                                                                                                                                                                                                                                                                                                            |
96*fa44fe6aSInna Palant
97*fa44fe6aSInna Palant## Original docs
98*fa44fe6aSInna Palant
99*fa44fe6aSInna PalantInsets for Jetpack Compose takes a lot of the ideas which drove [Insetter][insetter-view] for views, and applies them for use in composables.
100*fa44fe6aSInna Palant
101*fa44fe6aSInna Palant## Usage
102*fa44fe6aSInna PalantTo setup Insets in your composables, you need to call the `ProvideWindowInsets` function and
103*fa44fe6aSInna Palantwrap your content. This would typically be done near the top level of your composable hierarchy:
104*fa44fe6aSInna Palant
105*fa44fe6aSInna Palant``` kotlin
106*fa44fe6aSInna PalantsetContent {
107*fa44fe6aSInna Palant  MaterialTheme {
108*fa44fe6aSInna Palant    ProvideWindowInsets {
109*fa44fe6aSInna Palant      // your content
110*fa44fe6aSInna Palant    }
111*fa44fe6aSInna Palant  }
112*fa44fe6aSInna Palant}
113*fa44fe6aSInna Palant```
114*fa44fe6aSInna Palant
115*fa44fe6aSInna Palant!!! note
116*fa44fe6aSInna Palant    **This library does not disable window decor fitting.** For your view hierarchy to able to receive insets, you need to make sure to call: [`WindowCompat.setDecorFitsSystemWindows(window, false)`](https://developer.android.com/reference/androidx/core/view/WindowCompat#setDecorFitsSystemWindows(android.view.Window,%20boolean)) from your Activity. You also need to set the system bar backgrounds to be transparent, which can be done with our [System UI Controller](../systemuicontroller) library.
117*fa44fe6aSInna Palant
118*fa44fe6aSInna Palant`ProvideWindowInsets` allows the library to set an [`OnApplyWindowInsetsListener`][insetslistener] on your content's host view. That listener is used to update the value of a composition local bundled in this library: `LocalWindowInsets`.
119*fa44fe6aSInna Palant
120*fa44fe6aSInna Palant`LocalWindowInsets` holds an instance of `WindowInsets` which contains the value of various [WindowInsets][insets] [types][insettypes]. You can use the values manually like so:
121*fa44fe6aSInna Palant
122*fa44fe6aSInna Palant``` kotlin
123*fa44fe6aSInna Palant@Composable
124*fa44fe6aSInna Palantfun ImeAvoidingBox() {
125*fa44fe6aSInna Palant    val insets = LocalWindowInsets.current
126*fa44fe6aSInna Palant
127*fa44fe6aSInna Palant    val imeBottom = with(LocalDensity.current) { insets.ime.bottom.toDp() }
128*fa44fe6aSInna Palant    Box(Modifier.padding(bottom = imeBottom))
129*fa44fe6aSInna Palant}
130*fa44fe6aSInna Palant```
131*fa44fe6aSInna Palant
132*fa44fe6aSInna Palant...but we also provide some easy-to-use [Modifier][modifier]s.
133*fa44fe6aSInna Palant
134*fa44fe6aSInna Palant### Modifiers
135*fa44fe6aSInna Palant
136*fa44fe6aSInna PalantWe provide two types of modifiers for easy handling of insets: padding and size.
137*fa44fe6aSInna Palant
138*fa44fe6aSInna Palant#### Padding modifiers
139*fa44fe6aSInna PalantThe padding modifiers allow you to apply padding to a composable which matches a specific type of inset. Currently we provide:
140*fa44fe6aSInna Palant
141*fa44fe6aSInna Palant- [`Modifier.statusBarsPadding()`](../api/insets/com.google.accompanist.insets/status-bars-padding.html)
142*fa44fe6aSInna Palant- [`Modifier.navigationBarsPadding()`](../api/insets/com.google.accompanist.insets/navigation-bars-padding.html)
143*fa44fe6aSInna Palant- [`Modifier.systemBarsPadding()`](../api/insets/com.google.accompanist.insets/system-bars-padding.html)
144*fa44fe6aSInna Palant- [`Modifier.imePadding()`](../api/insets/com.google.accompanist.insets/ime-padding.html)
145*fa44fe6aSInna Palant- [`Modifier.navigationBarsWithImePadding()`](../api/insets/com.google.accompanist.insets/navigation-bars-with-ime-padding.html)
146*fa44fe6aSInna Palant- [`Modifier.cutoutPadding()`](../api/insets/com.google.accompanist.insets/cutout-padding.html)
147*fa44fe6aSInna Palant
148*fa44fe6aSInna PalantThese are commonly used to move composables out from under the system bars. The common example would be a [`FloatingActionButton`][fab]:
149*fa44fe6aSInna Palant
150*fa44fe6aSInna Palant``` kotlin
151*fa44fe6aSInna PalantFloatingActionButton(
152*fa44fe6aSInna Palant    onClick = { /* TODO */ },
153*fa44fe6aSInna Palant    modifier = Modifier
154*fa44fe6aSInna Palant        .align(Alignment.BottomEnd)
155*fa44fe6aSInna Palant        .padding(16.dp) // normal 16dp of padding for FABs
156*fa44fe6aSInna Palant        .navigationBarsPadding() // Move it out from under the nav bar
157*fa44fe6aSInna Palant) {
158*fa44fe6aSInna Palant    Icon(imageVector = Icons.Default.Add, contentDescription = null)
159*fa44fe6aSInna Palant}
160*fa44fe6aSInna Palant```
161*fa44fe6aSInna Palant
162*fa44fe6aSInna Palant#### Size modifiers
163*fa44fe6aSInna PalantThe size modifiers allow you to match the size of a composable to a specific type of inset. Currently we provide:
164*fa44fe6aSInna Palant
165*fa44fe6aSInna Palant- [`Modifier.statusBarsHeight()`](../api/insets/com.google.accompanist.insets/status-bars-height.html)
166*fa44fe6aSInna Palant- [`Modifier.navigationBarsHeight()`](../api/insets/com.google.accompanist.insets/navigation-bars-height.html)
167*fa44fe6aSInna Palant- [`Modifier.navigationBarsWidth()`](../api/insets/com.google.accompanist.insets/navigation-bars-width.html)
168*fa44fe6aSInna Palant
169*fa44fe6aSInna PalantThese are commonly used to allow composables behind the system bars, to provide background protection, or similar:
170*fa44fe6aSInna Palant
171*fa44fe6aSInna Palant``` kotlin
172*fa44fe6aSInna PalantSpacer(
173*fa44fe6aSInna Palant    Modifier
174*fa44fe6aSInna Palant        .background(Color.Black.copy(alpha = 0.7f))
175*fa44fe6aSInna Palant        .statusBarsHeight() // Match the height of the status bar
176*fa44fe6aSInna Palant        .fillMaxWidth()
177*fa44fe6aSInna Palant)
178*fa44fe6aSInna Palant```
179*fa44fe6aSInna Palant
180*fa44fe6aSInna Palant### PaddingValues
181*fa44fe6aSInna PalantCompose also provides the concept of [`PaddingValues`][paddingvalues], a data class which contains the padding values to be applied on all dimensions (similar to a rect). This is commonly used with container composables, such as [`LazyColumn`][lazycolumn], to set the content padding.
182*fa44fe6aSInna Palant
183*fa44fe6aSInna PalantYou may want to use inset values for content padding, so this library provides the [`rememberInsetsPaddingValues()`](..//api/insets/com.google.accompanist.insets/remember-insets-padding-values.html) extension function to convert between `Insets` and [`PaddingValues`][paddingvalues]. Here's an example of using the system bars insets:
184*fa44fe6aSInna Palant
185*fa44fe6aSInna Palant``` kotlin
186*fa44fe6aSInna PalantLazyColumn(
187*fa44fe6aSInna Palant    contentPadding = rememberInsetsPaddingValues(
188*fa44fe6aSInna Palant        insets = LocalWindowInsets.current.systemBars,
189*fa44fe6aSInna Palant        applyTop = true,
190*fa44fe6aSInna Palant        applyBottom = true,
191*fa44fe6aSInna Palant    )
192*fa44fe6aSInna Palant) {
193*fa44fe6aSInna Palant    // content
194*fa44fe6aSInna Palant}
195*fa44fe6aSInna Palant```
196*fa44fe6aSInna Palant
197*fa44fe6aSInna PalantFor a more complex example, see the [`EdgeToEdgeLazyColumn`](https://github.com/google/accompanist/blob/main/sample/src/main/java/com/google/accompanist/sample/insets/EdgeToEdgeLazyColumn.kt) example:
198*fa44fe6aSInna Palant
199*fa44fe6aSInna Palant<a href="images/edge-to-edge-list.jpg">
200*fa44fe6aSInna Palant<img src="images/edge-to-edge-list.jpg" width=300>
201*fa44fe6aSInna Palant</a>
202*fa44fe6aSInna Palant
203*fa44fe6aSInna Palant## Inset-aware layouts (`insets-ui`)
204*fa44fe6aSInna Palant
205*fa44fe6aSInna Palant!!! warning
206*fa44fe6aSInna Palant    **This library is deprecated, with [official support](https://android-review.googlesource.com/c/platform/frameworks/support/+/2667875) in androidx.compose.material.** The original documentation is below.
207*fa44fe6aSInna Palant
208*fa44fe6aSInna PalantUnfortunately, most of Compose Material's layouts do not support the use of content padding, which means that the following code probably doesn't produce the effect you want:
209*fa44fe6aSInna Palant
210*fa44fe6aSInna Palant``` kotlin
211*fa44fe6aSInna Palant// �� This likely doesn't do what you want
212*fa44fe6aSInna PalantTopAppBar(
213*fa44fe6aSInna Palant    // content
214*fa44fe6aSInna Palant    modifier = Modifier.statusBarsPadding()
215*fa44fe6aSInna Palant)
216*fa44fe6aSInna Palant```
217*fa44fe6aSInna Palant
218*fa44fe6aSInna PalantTo workaround this, we provide the `insets-ui` companion library which contains versions of commonly used layouts, with the addition of a `contentPadding` parameter. The example below is using our [`TopAppBar`](../api/insets-ui/com.google.accompanist.insets.ui/-top-app-bar.html) layout, providing the status bar insets to use as content padding:
219*fa44fe6aSInna Palant
220*fa44fe6aSInna Palant``` kotlin
221*fa44fe6aSInna Palantimport com.google.accompanist.insets.ui.TopAppBar
222*fa44fe6aSInna Palant
223*fa44fe6aSInna PalantTopAppBar(
224*fa44fe6aSInna Palant    contentPadding = rememberInsetsPaddingValues(
225*fa44fe6aSInna Palant        insets = LocalWindowInsets.current.statusBars,
226*fa44fe6aSInna Palant        applyStart = true,
227*fa44fe6aSInna Palant        applyTop = true,
228*fa44fe6aSInna Palant        applyEnd = true,
229*fa44fe6aSInna Palant    )
230*fa44fe6aSInna Palant) {
231*fa44fe6aSInna Palant    // content
232*fa44fe6aSInna Palant}
233*fa44fe6aSInna Palant```
234*fa44fe6aSInna Palant
235*fa44fe6aSInna PalantThe library also provides a modified copy of Compose Material's [`Scaffold`](https://developer.android.com/reference/kotlin/androidx/compose/material/package-summary#Scaffold(androidx.compose.ui.Modifier,androidx.compose.material.ScaffoldState,kotlin.Function0,kotlin.Function0,kotlin.Function1,kotlin.Function0,androidx.compose.material.FabPosition,kotlin.Boolean,kotlin.Function1,kotlin.Boolean,androidx.compose.ui.graphics.Shape,androidx.compose.ui.unit.Dp,androidx.compose.ui.graphics.Color,androidx.compose.ui.graphics.Color,androidx.compose.ui.graphics.Color,androidx.compose.ui.graphics.Color,androidx.compose.ui.graphics.Color,kotlin.Function1)) which better supports edge-to-edge layouts, by drawing the top and bottom bars over the content.
236*fa44fe6aSInna Palant
237*fa44fe6aSInna Palant``` kotlin
238*fa44fe6aSInna PalantScaffold(
239*fa44fe6aSInna Palant    topBar = {
240*fa44fe6aSInna Palant        // We use TopAppBar from accompanist-insets-ui which allows us to provide
241*fa44fe6aSInna Palant        // content padding matching the system bars insets.
242*fa44fe6aSInna Palant        TopAppBar(
243*fa44fe6aSInna Palant            title = { Text(stringResource(R.string.insets_title_list)) },
244*fa44fe6aSInna Palant            backgroundColor = MaterialTheme.colors.surface.copy(alpha = 0.9f),
245*fa44fe6aSInna Palant            contentPadding = rememberInsetsPaddingValues(
246*fa44fe6aSInna Palant                LocalWindowInsets.current.statusBars,
247*fa44fe6aSInna Palant                applyBottom = false,
248*fa44fe6aSInna Palant            ),
249*fa44fe6aSInna Palant        )
250*fa44fe6aSInna Palant    },
251*fa44fe6aSInna Palant    bottomBar = {
252*fa44fe6aSInna Palant        // We add a spacer as a bottom bar, which is the same height as
253*fa44fe6aSInna Palant        // the navigation bar
254*fa44fe6aSInna Palant        Spacer(Modifier.navigationBarsHeight().fillMaxWidth())
255*fa44fe6aSInna Palant    },
256*fa44fe6aSInna Palant) { contentPadding ->
257*fa44fe6aSInna Palant    // We apply the contentPadding passed to us from the Scaffold
258*fa44fe6aSInna Palant    Box(Modifier.padding(contentPadding)) {
259*fa44fe6aSInna Palant        // content
260*fa44fe6aSInna Palant    }
261*fa44fe6aSInna Palant}
262*fa44fe6aSInna Palant```
263*fa44fe6aSInna Palant
264*fa44fe6aSInna PalantSee the [API docs](../api/insets-ui/com.google.accompanist.insets.ui/) for a list of the other layouts provided in the library.
265*fa44fe6aSInna Palant
266*fa44fe6aSInna Palant### Animated Insets support
267*fa44fe6aSInna Palant
268*fa44fe6aSInna Palant=== "Info"
269*fa44fe6aSInna Palant
270*fa44fe6aSInna Palant    ![](images/ime-insets.gif){: align=right loading=lazy }
271*fa44fe6aSInna Palant
272*fa44fe6aSInna Palant    The library now has experimental support for [`WindowInsetsAnimations`](https://developer.android.com/reference/android/view/WindowInsetsAnimation), allowing your content is react to inset animations, such as the on screen-keyboard (IME) being animated on/off screen. The `imePadding()` and `navigationBarsWithImePadding()` modifiers are available especially for this use-case.
273*fa44fe6aSInna Palant
274*fa44fe6aSInna Palant    This functionality works wherever [WindowInsetsAnimationCompat](https://developer.android.com/reference/androidx/core/view/WindowInsetsAnimationCompat) works, which at the time or writing is on devices running API 21+.
275*fa44fe6aSInna Palant
276*fa44fe6aSInna Palant    To enable animated insets support, you need need to new `ProvideWindowInsets` overload, and set `windowInsetsAnimationsEnabled = true`.
277*fa44fe6aSInna Palant
278*fa44fe6aSInna Palant=== "Usage"
279*fa44fe6aSInna Palant
280*fa44fe6aSInna Palant    ``` kotlin
281*fa44fe6aSInna Palant    ProvideWindowInsets(windowInsetsAnimationsEnabled = true) {
282*fa44fe6aSInna Palant        // content
283*fa44fe6aSInna Palant    }
284*fa44fe6aSInna Palant    ```
285*fa44fe6aSInna Palant
286*fa44fe6aSInna Palant    You can then use the new `navigationBarsWithImePadding()` modifier like so:
287*fa44fe6aSInna Palant
288*fa44fe6aSInna Palant    ``` kotlin
289*fa44fe6aSInna Palant    OutlinedTextField(
290*fa44fe6aSInna Palant        // other params,
291*fa44fe6aSInna Palant        modifier = Modifier.navigationBarsWithImePadding()
292*fa44fe6aSInna Palant    )
293*fa44fe6aSInna Palant    ```
294*fa44fe6aSInna Palant
295*fa44fe6aSInna Palant    See the [ImeAnimationSample](https://github.com/google/accompanist/blob/main/sample/src/main/java/com/google/accompanist/sample/insets/ImeAnimationSample.kt) for a working example.
296*fa44fe6aSInna Palant
297*fa44fe6aSInna Palant### IME animations
298*fa44fe6aSInna PalantIf you're using the animation insets support for IME/keyboard animations, you also need to ensure that the activity's `windowSoftInputMode` is set to `adjustResize`:
299*fa44fe6aSInna Palant
300*fa44fe6aSInna Palant``` xml
301*fa44fe6aSInna Palant<activity
302*fa44fe6aSInna Palant      android:name=".MyActivity"
303*fa44fe6aSInna Palant      android:windowSoftInputMode="adjustResize">
304*fa44fe6aSInna Palant</activity>
305*fa44fe6aSInna Palant```
306*fa44fe6aSInna Palant
307*fa44fe6aSInna PalantThe default value of `windowSoftInputMode` _should_ work, but Compose does not currently set the flags necessary (see [here](https://issuetracker.google.com/154101484)).
308*fa44fe6aSInna Palant
309*fa44fe6aSInna Palant## �� Experimental
310*fa44fe6aSInna Palant
311*fa44fe6aSInna PalantThe features below are experimental, and require developers to [opt-in](https://kotlinlang.org/docs/reference/opt-in-requirements.html).
312*fa44fe6aSInna Palant
313*fa44fe6aSInna Palant### Controlling the IME (on-screen keyboard)
314*fa44fe6aSInna Palant
315*fa44fe6aSInna Palant=== "Info"
316*fa44fe6aSInna Palant
317*fa44fe6aSInna Palant    ![](images/ime-scroll.gif){: loading=lazy align=right }
318*fa44fe6aSInna Palant
319*fa44fe6aSInna Palant    This library also has support for controlling the IME from scroll gestures, allowing your scrollable components to pull/push the IME on/off screen. This is achieved through the built-in [`NestedScrollConnection`](https://developer.android.com/reference/kotlin/androidx/compose/ui/gesture/nestedscroll/NestedScrollConnection) implementation returned by [`rememberImeNestedScrollConnection()`](../api/insets/com.google.accompanist.insets/remember-ime-nested-scroll-connection.html).
320*fa44fe6aSInna Palant
321*fa44fe6aSInna Palant    This functionality only works when running on devices with API 30+.
322*fa44fe6aSInna Palant
323*fa44fe6aSInna Palant=== "Usage"
324*fa44fe6aSInna Palant
325*fa44fe6aSInna Palant    ``` kotlin
326*fa44fe6aSInna Palant    // Here we're using a scrollable Column, but it also works with LazyColumn, etc.
327*fa44fe6aSInna Palant    Column(
328*fa44fe6aSInna Palant        // We use the nestedScroll modifier, passing in the
329*fa44fe6aSInna Palant        // the connection from rememberImeNestedScrollConnection()
330*fa44fe6aSInna Palant        modifier = Modifier
331*fa44fe6aSInna Palant            .nestedScroll(connection = rememberImeNestedScrollConnection())
332*fa44fe6aSInna Palant            .verticalScroll(state = rememberScrollState())
333*fa44fe6aSInna Palant    ) {
334*fa44fe6aSInna Palant        // list content
335*fa44fe6aSInna Palant    }
336*fa44fe6aSInna Palant    ```
337*fa44fe6aSInna Palant
338*fa44fe6aSInna Palant    See the [ImeAnimationSample](https://github.com/google/accompanist/blob/main/sample/src/main/java/com/google/accompanist/sample/insets/ImeAnimationSample.kt) for a working example.
339*fa44fe6aSInna Palant
340*fa44fe6aSInna Palant
341*fa44fe6aSInna Palant## Download
342*fa44fe6aSInna Palant
343*fa44fe6aSInna Palant[![Maven Central](https://img.shields.io/maven-central/v/com.google.accompanist/accompanist-insets)](https://search.maven.org/search?q=g:com.google.accompanist)
344*fa44fe6aSInna Palant
345*fa44fe6aSInna Palant```groovy
346*fa44fe6aSInna Palantrepositories {
347*fa44fe6aSInna Palant    mavenCentral()
348*fa44fe6aSInna Palant}
349*fa44fe6aSInna Palant
350*fa44fe6aSInna Palantdependencies {
351*fa44fe6aSInna Palant    implementation "com.google.accompanist:accompanist-insets:<version>"
352*fa44fe6aSInna Palant    // If using insets-ui
353*fa44fe6aSInna Palant    implementation "com.google.accompanist:accompanist-insets-ui:<version>"
354*fa44fe6aSInna Palant}
355*fa44fe6aSInna Palant```
356*fa44fe6aSInna Palant
357*fa44fe6aSInna PalantSnapshots of the development version are available in [Sonatype's `snapshots` repository][snap]. These are updated on every commit.
358*fa44fe6aSInna Palant
359*fa44fe6aSInna Palant## Something not working?
360*fa44fe6aSInna Palant
361*fa44fe6aSInna PalantIf you find that something isn't working correctly, here's a checklist to try:
362*fa44fe6aSInna Palant
363*fa44fe6aSInna Palant- Check that you've called [`WindowCompat.setDecorFitsSystemWindows(window, false)`](https://developer.android.com/reference/androidx/core/view/WindowCompat#setDecorFitsSystemWindows(android.view.Window,%20boolean)) in your Activity. Unless you do that, the window decor will consume the insets, and they will not be dispatched to your content.
364*fa44fe6aSInna Palant- If it's something related to the keyboard, check that the Activity's `windowSoftInputMode` is set to [`adjustResize`](https://developer.android.com/reference/android/view/WindowManager.LayoutParams#SOFT_INPUT_ADJUST_RESIZE). Without that, IME visibility changes will not be sent as inset changes.
365*fa44fe6aSInna Palant- Similarly, if you're setting [`android:windowFullscreen`](https://developer.android.com/reference/android/view/WindowManager.LayoutParams#FLAG_FULLSCREEN) to `true` (or using a `.Fullscreen` theme), be aware that `adjustResize` will not work. Please see the [documentation](https://developer.android.com/reference/android/view/WindowManager.LayoutParams#FLAG_FULLSCREEN) for an alternative.
366*fa44fe6aSInna Palant- If you're using `ProvideWindowInsets` (or `ViewWindowInsetObserver`) in multiple layers of your view hierarchy (i.e. in the activity, _and_ in a fragment), you need to turn off consuming of insets. By default `ProvideWindowInsets` and `ViewWindowInsetObserver` will completely consume any insets passed to it. In the previous example, this means that the activity content will get the insets, but the fragment won't. To disable consuming, pass `consumeWindowInsets = false` to `ProvideWindowInsets` or `ViewWindowInsetObserver.start()`.
367*fa44fe6aSInna Palant
368*fa44fe6aSInna Palant[compose]: https://developer.android.com/jetpack/compose
369*fa44fe6aSInna Palant[snap]: https://oss.sonatype.org/content/repositories/snapshots/com/google/accompanist/accompanist-insets/
370*fa44fe6aSInna Palant[insetter-view]: https://github.com/chrisbanes/insetter
371*fa44fe6aSInna Palant[insets]: https://developer.android.com/reference/kotlin/androidx/core/view/WindowInsetsCompat
372*fa44fe6aSInna Palant[insettypes]: https://developer.android.com/reference/kotlin/androidx/core/view/WindowInsetsCompat.Type
373*fa44fe6aSInna Palant[insetslistener]: https://developer.android.com/reference/kotlin/androidx/core/view/OnApplyWindowInsetsListener
374*fa44fe6aSInna Palant[modifier]: https://developer.android.com/reference/kotlin/androidx/compose/ui/Modifier
375*fa44fe6aSInna Palant[paddingvalues]: https://developer.android.com/reference/kotlin/androidx/compose/foundation/layout/PaddingValues
376*fa44fe6aSInna Palant[lazycolumn]: https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/package-summary#lazycolumn
377*fa44fe6aSInna Palant[fab]: https://developer.android.com/reference/kotlin/androidx/compose/material/package-summary#floatingactionbutton
378*fa44fe6aSInna Palant[api-type]: ../api/insets/com.google.accompanist.insets/-window-insets/-type/
379