我正在将 paging3 库与 Compose Multiplatform 结合使用。它正在工作,但我注意到每次收到新的分页数据时,消耗分页数据的组件都会重新渲染(可见闪存)。我相信这是因为检查加载或错误状态的when语句。
我想添加distinctUntilChangedBy来按events.loadstate.refresh进行过滤,但在调用collectAsLazyPagingItems之前,它在流程上不可用。
我应该如何修改此代码,以便它不会在每次消息事件数量发生变化时重新渲染?我只想对列表中的更改进行动画处理,而不渲染整个组件,这会导致现在出现明显的闪烁?
这基本上是一个聊天列表。每次收到新的聊天消息,都会将其插入数据库,并使分页数据失效,以加载最新的消息。
@Composable
fun MessageList(
pager: Flow<PagingData<MessageEvent>>?,
modifier: Modifier = Modifier,
) {
pager?.let { flow ->
val events = flow.collectAsLazyPagingItems()
when (events.loadState.refresh) {
LoadStateLoading -> {
CenteredProgressIndicator()
}
is LoadStateError -> {
val errorState = events.loadState.refresh as LoadStateError
ShowError(errorState)
}
else -> {
if (events.itemCount > 0) {
LazyColumn {
items(events.itemCount) { index ->
events[index]?.let {
MessageRow(it)
}
}
}
} else {
NoMessagesAvailable(modifier)
}
}
}
}
}
发生闪烁是因为在刷新列表时,您在很短的时间内将
loadState
设置为 LoadStateLoading
。因此,在很短的时间内,会显示 CenteredProgressIndicator()
。
您尚未在设置
loadState
的位置提供代码。但你可以做些什么来解决这个问题:
CenteredProgressIndicator()
(当列表数据仍为空时)PullRefresh
:为了实现此行为,您可以调整逻辑并引入另一个 loadState:
LoadStateLoading
用于列表为空时的初始加载LoadStateRefreshing
用于当列表中已有数据时刷新然后根据LoadState,显示相应的加载动画:
when (events.loadState.refresh) {
LoadStateLoading -> {
CenteredProgressIndicator()
}
is LoadStateError -> {
// ...
}
else -> {
// Code for SwipeRefresh
var refreshing by remember { mutableStateOf(false) }
val state = rememberPullRefreshState(refreshing)
if (events.loadState.refresh.equals(LoadStateRefresh) {
refreshing = true
}
Box() {
LazyColumn(Modifier.fillMaxSize()) {
// your LazyColumn
}
// small circular loading indicator
PullRefreshIndicator(refreshing, state, Modifier.align(Alignment.TopCenter))
}
}
}