Compose并未像View-based系统那样内建SwipeRefreshLayout
。但Compose鼓励你自行创建需要的可组合函数,它提供了足够的工具供你完成此任务。
在本篇博客中,我们将展示如何在Jetpack Compose中创建滑动刷新界面的过程。但请注意,以下代码相当简化,没有处理如何处理正在刷新等边缘情况,也没有添加动画以实现平滑的外观。同时,它也不会在释放后弹回,或在调用刷新操作之前显示任何刷新可能的指示。然而,它应该能够为你提供一个良好的起点。
首先,我们需要引入以下库:
implementation ("com.google.accompanist:accompanist-swiperefresh:0.18.0")
然后,我们创建一个SwipeRefresh
的可组合函数,以下是该函数的基本形式:
@Composable
fun SwipeRefresh(refreshing:Boolean,onRefresh:()-> Unit, content:@Composable () -> Unit){
var yOffset by remember{ mutableStateOf(0f)}
var triggerHeight by remember{ mutableStateOf(0)}
Box(modifier = Modifier
.onGloballyPositioned { triggerHeight = it.size.height }
.pointerInput(Unit) {
detectDragGestures { change, dragAmount ->
val originalY = change.position.y
val newY = yOffset + dragAmount.y
if (newY >= 0) {
yOffset = newY
change.consumePositionChange()
}
if (newY > triggerHeight && !refreshing) {
onRefresh()
}
}
}
.offset { IntOffset(0, yOffset.roundToInt()) }
){
if(refreshing){
CircularProgressIndicator()
}else{
content()
}
}
}
@Preview
@Composable
fun SwipeRefresh1(){
//使用remember实现状态存储,这里创建一个可观察的状态变量,用于表示是否正在刷新
var isRefreshing by remember{ mutableStateOf(false)}
//创建一个在Composable 生命周期内有效的协程作用域
val scope = rememberCoroutineScope()
SwipeRefresh(refreshing = isRefreshing, onRefresh = {
//这里执行刷新操作,例如获取最新数据等
//注意这是个suspend函数,应在协程上下文中执行
isRefreshing =true
scope.launch {
delay(2000) //模拟耗时操作,比如网络请求
isRefreshing=false
}
}, content = {
Text(text = "Pull down to refresh...", modifier = Modifier.fillMaxWidth())
})
}
小项目:上拉刷新和下来加载
@Preview
@Composable
fun refreshLoadUse() {
val refreshState = rememberSwipeRefreshState(isRefreshing = false)
val model = viewModel<RefreshLoadUseViewModel>()
val collectAsLazyPagingItems = model.datas.collectAsLazyPagingItems()
SwipeRefresh(state = refreshState, onRefresh = {
collectAsLazyPagingItems.refresh()
}) {
LazyColumn(modifier = Modifier
.fillMaxWidth()
.fillMaxSize(), content = {
itemsIndexed(collectAsLazyPagingItems) { _, refreshData ->
Box(
modifier = Modifier
.padding(horizontal = 14.dp, vertical = 4.dp)
.fillMaxWidth()
.height(50.dp)
.background(
Color.Green, shape = RoundedCornerShape(8.dp)
)
.border(
width = 1.dp,
color = Color.Red,
shape = RoundedCornerShape(8.dp)
)
.padding(start = 10.dp),
contentAlignment = Alignment.CenterStart
) {
Text(text = refreshData?.data ?: "")
}
}
when(collectAsLazyPagingItems.loadState.append){
is LoadState.Loading ->{
item {
Box(modifier = Modifier
.fillMaxWidth()
.height(50.dp),
contentAlignment = Alignment.Center){
Text(text = "--加载中--")
}
}
}else ->{
item {
Box(modifier = Modifier
.fillMaxWidth()
.height(50.dp), contentAlignment = Alignment.Center){
Text(text = "加载完成或者加载失败--")
}
}
}
}
})
}
}
data class RefreshData(val data:String)
class RefreshLoadUseViewModel : ViewModel() { val datas= Pager(PagingConfig(pageSize = 20)){ RefreshLoadUseSource() }.flow.cachedIn(viewModelScope) }