# Swipe Refresh for Jetpack Compose [![Maven Central](https://img.shields.io/maven-central/v/com.google.accompanist/accompanist-swiperefresh)](https://search.maven.org/search?q=g:com.google.accompanist) !!! warning **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. ## Migration Accompanist 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. A simple example is as follows: ```kotlin val viewModel: MyViewModel = viewModel() val refreshing by viewModel.isRefreshing val pullRefreshState = rememberPullRefreshState(refreshing, { viewModel.refresh() }) Box(Modifier.pullRefresh(pullRefreshState)) { LazyColumn(Modifier.fillMaxSize()) { ... } PullRefreshIndicator(refreshing, pullRefreshState, Modifier.align(Alignment.TopCenter)) } ``` ### Migration steps 1. Replace SwipeRefresh with a Box or other layout of your choice, save your `onRefresh` lambda for the next step. 2. Replace `rememberSwipeRefreshState()` with `rememberPullRefreshState(refreshing, onRefresh)` 3. Add either the default `PullRefreshIndicator` or your own custom implementation to your layout. ### Custom Indicator Instead of using the provided `PullRefreshIndicator` composable, you can create your own custom indicator. A 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). ## Original Docs A 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).
SwipeRefresh demo
## Usage To 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. The basic usage of a [`SwipeRefresh`][api_swiperefresh] using a ViewModel looks like so: ``` kotlin val viewModel: MyViewModel = viewModel() val isRefreshing by viewModel.isRefreshing.collectAsState() SwipeRefresh( state = rememberSwipeRefreshState(isRefreshing), onRefresh = { viewModel.refresh() }, ) { LazyColumn { items(30) { index -> // TODO: list items } } } ``` The 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). The 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: ``` kotlin SwipeRefresh( // ... ) { Column(Modifier.verticalScroll(rememberScrollState())) { // content } } ``` ### Indicating a refresh without swiping As this library is built with a separate state object, it's easy to display a refreshing indicator without a swipe to triggering it. The unrealistic example below displays a forever refreshing indicator: ``` kotlin val swipeRefreshState = rememberSwipeRefreshState(true) SwipeRefresh( state = swipeRefreshState, onRefresh = { /* todo */ }, ) { LazyColumn { items(30) { index -> // TODO: list items } } } ``` ## Indicator The 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. ### Customizing default indicator To customize the default indicator, we can provide our own `indicator` content block, to call [`SwipeRefreshIndicator()`][api_swiperefreshindicator] with customized parameters: === "Sample" ``` kotlin SwipeRefresh( state = /* ... */, onRefresh = /* ... */, indicator = { state, trigger -> SwipeRefreshIndicator( // Pass the SwipeRefreshState + trigger through state = state, refreshTriggerDistance = trigger, // Enable the scale animation scale = true, // Change the color and shape backgroundColor = MaterialTheme.colors.primary, shape = MaterialTheme.shapes.small, ) } ) ``` === "Demo video"
Tweaked indicator demo
### Custom indicator As 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. An example of a custom indicator is provided [here][sample_customindicator]. ## Download [![Maven Central](https://img.shields.io/maven-central/v/com.google.accompanist/accompanist-swiperefresh)](https://search.maven.org/search?q=g:com.google.accompanist) ```groovy repositories { mavenCentral() } dependencies { implementation "com.google.accompanist:accompanist-swiperefresh:" } ``` Snapshots of the development version are available in [Sonatype's `snapshots` repository][snap]. These are updated on every commit. [compose]: https://developer.android.com/jetpack/compose [snap]: https://oss.sonatype.org/content/repositories/snapshots/com/google/accompanist/accompanist-swiperefresh/ [api_swiperefreshstate]: ../api/swiperefresh/com.google.accompanist.swiperefresh/-swipe-refresh-state/ [api_swiperefreshindicator]: ../api/swiperefresh/com.google.accompanist.swiperefresh/-swipe-refresh-indicator.html [api_swiperefresh]: ../api/swiperefresh/com.google.accompanist.swiperefresh/-swipe-refresh.html [api_rememberstate]: ../api/swiperefresh/com.google.accompanist.swiperefresh/remember-swipe-refresh-state.html [sample_customindicator]: https://github.com/google/accompanist/blob/main/sample/src/main/java/com/google/accompanist/sample/swiperefresh/SwipeRefreshCustomIndicatorSample.kt [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) [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) [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) [verticalscroll]: https://developer.android.com/jetpack/compose/gestures#scroll-modifiers