android 在Compose中,PagingData / LazyPagingItems在从缓存返回数据之前返回0个项目,并且最初在Config上的Loading状态更改

pkwftd7m  于 2023-05-05  发布在  Android
关注(0)|答案(1)|浏览(225)

我有这个屏幕:

@Composable
fun ChatDetailsScreen(
    chatDetailsViewModel: ChatDetailsViewModel = hiltViewModel(),
    navigateUp: () -> Unit
) {
    val chatMessagesResponse = chatDetailsViewModel.chatMessagesResponse.collectAsLazyPagingItems()

    val itemsCount = chatMessagesResponse.itemSnapshotList.size
    val loadState = chatMessagesResponse.loadState.refresh

    Timber.d("chatMessagesResponse size $itemsCount, loadStatus: $loadState")

在打开的第一个屏幕上,有以下日志:

chatMessagesResponse size 0, loadStatus: Loading(endOfPaginationReached=false)
chatMessagesResponse size 0, loadStatus: Loading(endOfPaginationReached=false)
chatMessagesResponse size 15, loadStatus: NotLoading(endOfPaginationReached=false)
chatMessagesResponse size 15, loadStatus: NotLoading(endOfPaginationReached=false)
chatMessagesResponse size 30, loadStatus: NotLoading(endOfPaginationReached=false)

但是在配置更改(例如方向更改)后,再次出现size 0loadStatus: Loading,这导致在LazyColumn中重置滚动(列表大小从30更改为0,然后从0更改为30)并显示ProgressBar,尽管数据没有被刷新,但它是从该高速缓存返回的:

chatMessagesResponse size 0, loadStatus: Loading(endOfPaginationReached=false)
chatMessagesResponse size 30, loadStatus: NotLoading(endOfPaginationReached=false)

我希望只看到配置更改的第二行,但它仍然给了我size 0loadStatus: Loading,这打破了一切,这是非常恼人的...
在配置配置更改时,它重用缓存的数据,这就是为什么我马上得到30(每页15),但为什么我们在此之前得到0,我不明白...
p.s.:ViewModel:

@HiltViewModel
class ChatDetailsViewModel @Inject constructor(
    // ...
) : ViewModel() {
    
    val chatMessagesResponse = getChatMessagesUseCase(chatId)
                                 .cachedIn(viewModelScope)
}

同样的问题,如果你打开一些其他屏幕,并返回到这个,你希望看到相同的列表在最后滚动位置,但它重置它,也不应该显示任何进度条,因为没有新的请求触发...

eqzww0vc

eqzww0vc1#

将很快在新版本中修复:
这一问题已在内部得到修复,并将在下一版本中提供。下一个发布版本是TBD。
简而言之,修复的工作原理是在配置更改/导航后立即提供缓存数据。这可以防止列表在配置更改/导航之后立即没有项目,因此滚动状态将被保留,而不需要诸如comment#24之类的变通方法。
也就是说,它只在有缓存数据的情况下才起作用。这意味着您需要pager.flow.cachedIn(scope)。请注意,任何PagedDataMap/转换都应该在cachedIn()之前应用,例如

val pager = pager.flow.map { pagingData -> 
    pagingData.map {
       // map items
    }
}.cachedIn(scope)

https://issuetracker.google.com/issues/177245496#comment45

相关问题