LoginSignup
7
2

More than 1 year has passed since last update.

AccompanistのSwipeRefreshからcompose.materialのPullRefreshに置き換える

Posted at

Accompanist にあった SwipeRefresh が compose.material に PullRefresh として実装されました。
Accompanist 側にマイグレーションガイドがまだないので、どのように置き換えることになるのか書いていこうと思います。

Accompanist 0.27.0、compose.material 1.3.0 時点の内容になります。

基本的な置き換え

以下のような Accompanist の SwipeRefresh で実装された処理を置き換えていきます。

val viewModel: MyViewModel = viewModel()
val isRefreshing by viewModel.isRefreshing.collectAsState()

val state = rememberSwipeRefreshState(isRefreshing)

SwipeRefresh(
    state = state,
    onRefresh = { viewModel.refresh() },
) {
    LazyColumn {
        items(30) { index ->
            // list items
        }
    }
}

rememberSwipeRefreshState を rememberPullRefreshState に置き換えます。
また Pull された時のコールバックが State 側に移動しています。

// Before
// val state = rememberSwipeRefreshState(isRefreshing)

// After
val state = rememberPullRefreshState(
    refreshing = isRefreshing,
    onRefresh = { viewModel.refresh() }
)

SwipeRefreshBox + PullRefreshIndicator に置き換えます。
またリストのスクロールを検知するために Modifier#pullRefreshBox に設定する必要があります(Modifier#pullRefresh は内部で nestedScroll を実装している)。

// Before
// SwipeRefresh(
//     state = state,
//     onRefresh = { viewModel.refresh() },
// ) {
//     // contents
// }

// After
Box(modifier = Modifier.pullRefresh(state)) {
    // contents

    PullRefreshIndicator(
        refreshing = isRefreshing,
        state = state,
        modifier = Modifier.align(Alignment.TopCenter)
    )
}

挙動としては↓のようになり、大きな差がなく置き換えることができます。

Accompanist compose.material
Accompanist version compose.material version

全コード

  • Before
val viewModel: MyViewModel = viewModel()
val isRefreshing by viewModel.isRefreshing.collectAsState()

val state = rememberSwipeRefreshState(isRefreshing)

SwipeRefresh(
    state = state,
    onRefresh = { viewModel.refresh() },
) {
    LazyColumn {
        items(30) { index ->
            // list items
        }
    }
}
  • After
@Composable
fun SwipeRefreshSample() {
    val viewModel: MyViewModel = viewModel()
    val isRefreshing by viewModel.isRefreshing.collectAsState()

    val state = rememberPullRefreshState(
        refreshing = isRefreshing,
        onRefresh = { viewModel.refresh() }
    )

    Box(Modifier.pullRefresh(state)) {
        LazyColumn {
            items(30) { index ->
                // list items
            }
        }

        PullRefreshIndicator(
            refreshing = isRefreshing,
            state = state,
            modifier = Modifier.align(Alignment.TopCenter)
        )
    }
}

既存の API の移行先

Accompanist compose.material
SwipeRefresh(swipeEnabled) Modifier.pullRefresh(enabled)
SwipeRefresh(refreshTriggerDistance) rememberPullRefreshState(refreshThreshold)
SwipeRefresh(indicatorAlignment, indicatorPadding) PullRefreshIndicator の Composable 関数に対して配置するときに指定する
SwipeRefreshIndicator(backgroundColor, contentColor) PullRefreshIndicator(backgroundColor, contentColor)
SwipeRefreshIndicator(scale) PullRefreshIndicator(scale)
SwipeRefreshIndicator(refreshingOffset) rememberPullRefreshState(refreshingOffset)
ただし Indicator のサイズ + Offset で指定する必要がある
SwipeRefreshIndicator(largeIndication) -
(Modifier.scale で調整可能ではある)
SwipeRefreshIndicator(fade) -
SwipeRefreshIndicator(arrowEnabled) -
SwipeRefreshIndicator(shape) -
SwipeRefreshIndicator(elevation) -

Indicator のカスタマイズはまだパラメータが少ない状態なので、compose.material-1.3.0 時点では移行が難しい場合があるかもしれません。

参考

7
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
2