前言
在安卓开发中,下拉刷新是一个非常常用的功能,几乎只要是涉及到列表展示数据的界面都会用到它。
而 Compose 却直到 2022年10月份才在 compose.material:1.3.0 中添加了对下拉刷新的支持:Modifier.pullRefresh 。
在此之前,我们只能使用 accompanist-swiperefresh 来实现下拉刷新。
然而,更坑的是,Compose 对下拉刷新的支持是添加到 material 中的,而现在谷歌主推的却是 material3 ,你猜怎么着,诶,material3 不支持下拉刷新。并且由于 material 添加了 Modifier.pullRefresh ,accompanist-swiperefresh 就直接废弃了,不再维护:
This library is deprecated, with official pull refresh support in androidx.compose.material.pullrefresh.
我查了一下,虽然 material3 的路线图中有对下拉刷新的计划,但是等到发布不知道还得等几年,而且在谷歌的 Issue Trcker 也有人询问了这个进度,官方的回答是:
PullToRefresh is not currently on the M3 radar however you are welcome to file a feature request.
以上来自 【Android-Compose】Material3 新版下拉刷新 PullRefresh_jetpack compose material3下拉刷新-CSDN博客
随后我又查询了一下这两个的官方API,只存在于material1.3中,并不存在于material3中,请各位水文不要打着material3的名头,发无意义的文章
Modifier.PullRefresh
rememberPullRefreshState
使用爆红
material 中基础使用
fun Modifier.pullRefresh(
state: PullRefreshState,
enabled: Boolean = true
)
第一个参数用于存储下拉的进度,第二个代表是否启用。相关联的这个 State 自然也有对应的 remember 方法用于创建
/**
* 创建一个被 remember 的[PullRefreshState]
*
* 对 [refreshing] 的更改会更新 [PullRefreshState].
*
* @sample androidx.compose.material.samples.PullRefreshSample
*
* @param refreshing 布尔值,代表当前是否正在刷新
* @param onRefresh 刷新时的回调
* @param refreshThreshold 若超过此阈值,则放手后会触发 [onRefresh]
* @param refreshingOffset 刷新时指示器的底部位置
*/
@Composable
@ExperimentalMaterialApi
fun rememberPullRefreshState(
refreshing: Boolean,
onRefresh: () -> Unit,
refreshThreshold: Dp = PullRefreshDefaults.RefreshThreshold, // 80.dp
refreshingOffset: Dp = PullRefreshDefaults.RefreshingOffset, // 56.dp
): PullRefreshState
综合使用,示例代码如下
@OptIn(ExperimentalMaterialApi::class)
@Composable
fun SwipeToRefreshTest(
modifier: Modifier = Modifier
) {
val list = remember {
List(4){ "Item $it" }.toMutableStateList()
}
var refreshing by remember {
mutableStateOf(false)
}
// 用协程模拟一个耗时加载
val scope = rememberCoroutineScope()
val state = rememberPullRefreshState(refreshing = refreshing, onRefresh = {
scope.launch {
refreshing = true
delay(1000) // 模拟数据加载
list+="Item ${list.size+1}"
refreshing = false
}
})
Box(modifier = modifier
.fillMaxSize()
.pullRefresh(state)
){
LazyColumn(Modifier.fillMaxWidth()){
// ...
}
PullRefreshIndicator(refreshing, state, Modifier.align(Alignment.TopCenter))
}
}
以上来在 Jetpack Compose 博物馆 的教材
https://jetpackcompose.cn/docs/layout/pull_refresh/