1# Swipe Refresh for Jetpack Compose 2 3[](https://search.maven.org/search?q=g:com.google.accompanist) 4 5!!! warning 6 **This library is deprecated, with official pull refresh support in [androidx.compose.material.pullrefresh](https://developer.android.com/reference/kotlin/androidx/compose/material/pullrefresh/package-summary).** The migration guide and original documentation is below. 7 8## Migration 9 10Accompanist SwipeRefresh has been replaced by PullRefresh in [Compose Material 1.3.0](https://developer.android.com/jetpack/androidx/releases/compose-material#1.3.0). The implementation is similar but instead of being a Composable function, it is a Modifier that can be applied to a Composable function. 11 12A simple example is as follows: 13 14```kotlin 15val viewModel: MyViewModel = viewModel() 16val refreshing by viewModel.isRefreshing 17 18val pullRefreshState = rememberPullRefreshState(refreshing, { viewModel.refresh() }) 19 20Box(Modifier.pullRefresh(pullRefreshState)) { 21 LazyColumn(Modifier.fillMaxSize()) { 22 ... 23 } 24 25 PullRefreshIndicator(refreshing, pullRefreshState, Modifier.align(Alignment.TopCenter)) 26} 27``` 28 29### Migration steps 30 311. Replace SwipeRefresh with a Box or other layout of your choice, save your `onRefresh` lambda for the next step. 322. Replace `rememberSwipeRefreshState()` with `rememberPullRefreshState(refreshing, onRefresh)` 333. Add either the default `PullRefreshIndicator` or your own custom implementation to your layout. 34 35### Custom Indicator 36 37Instead of using the provided `PullRefreshIndicator` composable, you can create your own custom indicator. 38A full sample can be seen in the [Compose samples](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:compose/material/material/samples/src/main/java/androidx/compose/material/samples/PullRefreshSamples.kt;l=91?q=pullrefresh). 39 40## Original Docs 41 42A library which provides a layout which provides the swipe-to-refresh UX pattern, similar to Android's [`SwipeRefreshLayout`](https://developer.android.com/training/swipe/add-swipe-interface). 43 44<figure> 45 <video width="400" controls loop> 46 <source src="demo.mp4" type="video/mp4"> 47 Your browser does not support the video tag. 48 </video> 49 <figcaption>SwipeRefresh demo</figcaption> 50</figure> 51 52## Usage 53 54To implement this UX pattern there are two key APIs which are needed: [`SwipeRefresh`][api_swiperefresh], which is provides the layout, and [`rememberSwipeRefreshState()`][api_rememberstate] which provides some remembered state. 55 56The basic usage of a [`SwipeRefresh`][api_swiperefresh] using a ViewModel looks like so: 57 58``` kotlin 59val viewModel: MyViewModel = viewModel() 60val isRefreshing by viewModel.isRefreshing.collectAsState() 61 62SwipeRefresh( 63 state = rememberSwipeRefreshState(isRefreshing), 64 onRefresh = { viewModel.refresh() }, 65) { 66 LazyColumn { 67 items(30) { index -> 68 // TODO: list items 69 } 70 } 71} 72``` 73 74The full example, including the view model implementation can be found [here](https://github.com/google/accompanist/blob/main/sample/src/main/java/com/google/accompanist/sample/swiperefresh/DocsSamples.kt). 75 76The content needs to be 'vertically scrollable' for `SwipeRefresh()` to be able to react to swipe gestures. Layouts such as [`LazyColumn`][lazycolumn] are automatically vertically scrollable, but others such as [`Column`][column] or [`LazyRow`][lazyrow] are not. In those instances, you can provide a [`Modifier.verticalScroll`][verticalscroll] modifier to that content like so: 77 78``` kotlin 79SwipeRefresh( 80 // ... 81) { 82 Column(Modifier.verticalScroll(rememberScrollState())) { 83 // content 84 } 85} 86``` 87 88 89### Indicating a refresh without swiping 90 91As this library is built with a separate state object, it's easy to display a refreshing indicator without a swipe to triggering it. 92 93The unrealistic example below displays a forever refreshing indicator: 94 95``` kotlin 96val swipeRefreshState = rememberSwipeRefreshState(true) 97 98SwipeRefresh( 99 state = swipeRefreshState, 100 onRefresh = { /* todo */ }, 101) { 102 LazyColumn { 103 items(30) { index -> 104 // TODO: list items 105 } 106 } 107} 108``` 109 110## Indicator 111 112The library provides a default indicator: [`SwipeRefreshIndicator()`][api_swiperefreshindicator], which `SwipeRefresh` uses automatically. You can customize the default indicator, and even provide your own indicator content using the `indicator` slot. 113 114### Customizing default indicator 115 116To customize the default indicator, we can provide our own `indicator` content block, to call [`SwipeRefreshIndicator()`][api_swiperefreshindicator] with customized parameters: 117 118=== "Sample" 119 120 ``` kotlin 121 SwipeRefresh( 122 state = /* ... */, 123 onRefresh = /* ... */, 124 indicator = { state, trigger -> 125 SwipeRefreshIndicator( 126 // Pass the SwipeRefreshState + trigger through 127 state = state, 128 refreshTriggerDistance = trigger, 129 // Enable the scale animation 130 scale = true, 131 // Change the color and shape 132 backgroundColor = MaterialTheme.colors.primary, 133 shape = MaterialTheme.shapes.small, 134 ) 135 } 136 ) 137 ``` 138 139=== "Demo video" 140 141 <figure> 142 <video width="480" controls loop> 143 <source src="tweaked.mp4" type="video/mp4"> 144 Your browser does not support the video tag. 145 </video> 146 <figcaption>Tweaked indicator demo</figcaption> 147 </figure> 148 149### Custom indicator 150 151As mentioned, you can also provide your own custom indicator content. A [`SwipeRefreshState`][api_swiperefreshstate] is provided to `indicator` content slot, which contains the information necessary to react to a swipe refresh gesture. 152 153An example of a custom indicator is provided [here][sample_customindicator]. 154 155## Download 156 157[](https://search.maven.org/search?q=g:com.google.accompanist) 158 159```groovy 160repositories { 161 mavenCentral() 162} 163 164dependencies { 165 implementation "com.google.accompanist:accompanist-swiperefresh:<version>" 166} 167``` 168 169Snapshots of the development version are available in [Sonatype's `snapshots` repository][snap]. These are updated on every commit. 170 171 [compose]: https://developer.android.com/jetpack/compose 172 [snap]: https://oss.sonatype.org/content/repositories/snapshots/com/google/accompanist/accompanist-swiperefresh/ 173 [api_swiperefreshstate]: ../api/swiperefresh/com.google.accompanist.swiperefresh/-swipe-refresh-state/ 174 [api_swiperefreshindicator]: ../api/swiperefresh/com.google.accompanist.swiperefresh/-swipe-refresh-indicator.html 175 [api_swiperefresh]: ../api/swiperefresh/com.google.accompanist.swiperefresh/-swipe-refresh.html 176 [api_rememberstate]: ../api/swiperefresh/com.google.accompanist.swiperefresh/remember-swipe-refresh-state.html 177 [sample_customindicator]: https://github.com/google/accompanist/blob/main/sample/src/main/java/com/google/accompanist/sample/swiperefresh/SwipeRefreshCustomIndicatorSample.kt 178 [lazycolumn]: https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/package-summary#LazyColumn(androidx.compose.ui.Modifier,androidx.compose.foundation.lazy.LazyListState,androidx.compose.foundation.layout.PaddingValues,kotlin.Boolean,androidx.compose.foundation.layout.Arrangement.Vertical,androidx.compose.ui.Alignment.Horizontal,androidx.compose.foundation.gestures.FlingBehavior,kotlin.Function1) 179 [column]: https://developer.android.com/reference/kotlin/androidx/compose/foundation/layout/package-summary#Column(androidx.compose.ui.Modifier,androidx.compose.foundation.layout.Arrangement.Vertical,androidx.compose.ui.Alignment.Horizontal,kotlin.Function1) 180 [lazyrow]: https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/package-summary#LazyRow(androidx.compose.ui.Modifier,androidx.compose.foundation.lazy.LazyListState,androidx.compose.foundation.layout.PaddingValues,kotlin.Boolean,androidx.compose.foundation.layout.Arrangement.Horizontal,androidx.compose.ui.Alignment.Vertical,androidx.compose.foundation.gestures.FlingBehavior,kotlin.Function1) 181 [verticalscroll]: https://developer.android.com/jetpack/compose/gestures#scroll-modifiers 182