Swipe Refresh for Jetpack Compose
Migration
Accompanist SwipeRefresh has been replaced by PullRefresh in
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:
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
- Replace SwipeRefresh with a Box or other layout of your choice, save your
onRefresh
lambda for the next step.
- Replace
rememberSwipeRefreshState()
with
rememberPullRefreshState(refreshing, onRefresh)
- 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
.
Original Docs
A library which provides a layout which provides the swipe-to-refresh UX pattern, similar to Android's
SwipeRefreshLayout
.
Usage
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
}
}
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:
val
swipeRefreshState
=
rememberSwipeRefreshState
(
true
)
SwipeRefresh
(
state
=
swipeRefreshState
,
onRefresh
=
{
/* todo */
},
)
{
LazyColumn
{
items
(
30
)
{
index
->
// TODO: list items
}
}
}
Indicator
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.
Customizing default indicator
To customize the default indicator, we can provide our own
indicator
content block, to call
SwipeRefreshIndicator()
with customized parameters:
Custom indicator
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
.
Download
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.