1*fa44fe6aSInna Palant# Insets for Jetpack Compose 2*fa44fe6aSInna Palant 3*fa44fe6aSInna Palant[](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 {: 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 {: 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[](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