Compose 组合项 - 下拉刷新 pullRefresh

一、概念

1.1 修饰符 Modifier.pullRefresh()

功能实现采用的是 Modifier 修饰符而不是一个单独的组合项,所以需要提供一个父容器来存放内容和下拉指示器。需求是下拉指示器显示在内容之上,因此选择 Box,注意内容必须具备纵向滑动能力否则无法触发(非LazyColumn可设置Modifier.verticalScroll)。

|-------------------------------------------------------------------------------------------------|
| fun Modifier.pullRefresh( state: PullRefreshState, //下拉刷新的状态管理 enabled: Boolean = true //是否启用 ) |

1.2 状态管理 rememberPullRefreshState()

用于管理刷新状态和刷新业务。通过实例.progress可以获取进度来自定义指示器或动画。

|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| fun rememberPullRefreshState( refreshing: Boolean, //是否在刷新 onRefresh: () -> Unit, //处理刷新的业务逻辑,结束后将刷新状态设为false refreshThreshold: Dp = PullRefreshDefaults.RefreshThreshold, refreshingOffset: Dp = PullRefreshDefaults.RefreshingOffset, ): PullRefreshState |

1.3 下拉指示器 PullRefreshIndicator

|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| fun PullRefreshIndicator( refreshing: Boolean, //是否在刷新 state: PullRefreshState, //下拉刷新的状态管理 modifier: Modifier = Modifier, backgroundColor: Color = MaterialTheme.colors.surface, contentColor: Color = contentColorFor(backgroundColor), scale: Boolean = false ) |

二、代码示例

2.1 简单封装

Kotlin 复制代码
@Composable
fun Demo(
    onRefreshing: () -> Unit,    //刷新时的回调
    modifier: Modifier = Modifier,
    content: @Composable () -> Unit,    //包裹的内容(必须具备纵向滑动否则无法触发)
) {
    //是否在刷新
    var isRefreshing by remember{ mutableStateOf(false) }
    //下拉刷新的状态管理
    val pullRefreshState = rememberPullRefreshState(
        refreshing = isRefreshing,
        onRefresh = { isRefreshing = true }
    )
    //刷新时的业务处理
    if (isRefreshing) {
        onRefreshing()
        isRefreshing = false    //刷新业务执行完毕后修改状态
    }
    Box(modifier = modifier
        .fillMaxSize()
        .pullRefresh(state = pullRefreshState)
    ) {
        content()
        PullRefreshIndicator(
            refreshing = isRefreshing,
            state = pullRefreshState,
            modifier = Modifier.align(Alignment.TopCenter)
        )
    }
}

2.2 结合 Paging 使用

Kotlin 复制代码
@Composable
fun DemoScreen(
    viewModel: DemoViewModel = viewModel()
) {
    val lazyPagingItems = viewModel.pagingDataFlow.collectAsLazyPagingItems() //获取Paging数据
    Demo(
        onRefreshing = { lazyPagingItems.refresh() } //刷新Paging
    ) {
        Content(lazyPagingItems = lazyPagingItems)
    }
}

@Composable
fun Content(
    lazyPagingItems: LazyPagingItems<...>,
    lazyListState: LazyListState = rememberLazyListState(),
    modifier: Modifier = Modifier
) {
    LazyColumn(
        modifier = modifier.fillMaxSize(),
        state = lazyListState
    ) {
        items(
            count = lazyPagingItems.itemCount,
            key = lazyPagingItems.itemKey { it.id }
        ) { index ->
            val bean = lazyPagingItems[index]
            if (bean != null) {
                Item(...)    //为Item设置内容
            } else {
                Text("")    //内容为空时显示的占位Item
            }
        }
    }
}
相关推荐
砖厂小工1 小时前
Compose 中函数引用 vs Lambda:到底该用哪个?
android
Kapaseker12 小时前
详解 Compose background 的重组陷阱
android·kotlin
黄林晴12 小时前
Kotlin 2.3.20-RC2 来了!JPA 开发者狂喜,6 大更新一文速览
android·kotlin
kymjs张涛1 天前
OpenClaw 学习小组:初识
android·linux·人工智能
范特西林1 天前
实战演练——从零实现一个高性能 Binder 服务
android
范特西林1 天前
代码的生成:AIDL 编译器与 Parcel 的序列化艺术
android
范特西林1 天前
深入内核:Binder 驱动的内存管理与事务调度
android
范特西林1 天前
解剖麻雀:Binder 通信的整体架构全景图
android
范特西林1 天前
破冰之旅:为什么 Android 选择了 Binder?
android
奔跑中的蜗牛6661 天前
一次播放器架构升级:Android 直播间 ANR 下降 60%
android