A library which provides a layout which provides the swipe-to-refresh UX pattern, similar to Android's SwipeRefreshLayout
.
To implement this UX pattern there are two key APIs which are needed: SwipeRefresh
, which is provides the layout, and rememberSwipeRefreshState()
which provides some remembered state.
The basic usage of a SwipeRefresh
using a ViewModel looks like so:
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.
The content needs to be 'vertically scrollable' for SwipeRefresh()
to be able to react to swipe gestures. Layouts such as LazyColumn
are automatically vertically scrollable, but others such as Column
or LazyRow
are not. In those instances, you can provide a Modifier.verticalScroll
modifier to that content like so:
SwipeRefresh(
// ...
) {
Column(Modifier.verticalScroll(rememberScrollState())) {
// content
}
}
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:
val swipeRefreshState = rememberSwipeRefreshState(true)
SwipeRefresh(
state = swipeRefreshState,
onRefresh = { /* todo */ },
) {
LazyColumn {
items(30) { index ->
// TODO: list items
}
}
}
The library provides a default indicator: SwipeRefreshIndicator()
, which SwipeRefresh
uses automatically. You can customize the default indicator, and even provide your own indicator content using the indicator
slot.
To customize the default indicator, we can provide our own indicator
content block, to call 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"
<figure>
<video width="480" controls loop>
<source src="tweaked.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
<figcaption>Tweaked indicator demo</figcaption>
</figure>
As mentioned, you can also provide your own custom indicator content. A 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.
repositories {
mavenCentral()
}
dependencies {
implementation "com.google.accompanist:accompanist-swiperefresh:<version>"
}
Snapshots of the development version are available in Sonatype's snapshots
repository. These are updated on every commit.