![](/img/trans.png)
[英]Infinite recomposition on LazyColumn items in Jetpack Compose
[英]Jetpack Compose: LazyColumn does not update items
我有一個來自 viewModel 的lazyColumn 接收列表來創建項目:
@Composable
fun HomeList(
modifier: Modifier = Modifier,
dataList: List<Data>,
listState: LazyListState = rememberLazyListState(),
onClickItem: (Data) -> Unit,
onLongPressItem: (Data) -> Unit
) {
LazyColumn(
modifier = modifier,
state = listState
) {
items(dataList) { data ->
Log.d(TAG, "HomeList: add data $data")
HomeListItem(
data = data,
onClick = onClickItem,
onLongPressed = onLongPressItem
)
}
}
}
該列表包裝在 viewModel 中的 stateFlow 中,並在 Composable 中收集為 state:
// viewModel
...
private val _uiState = MutableStateFlow(
HomeUiState(
...
homeList = listOf()
)
)
val uiState = _uiState as StateFlow<HomeUiState>
...
// HomeScreen
val uiState by viewModel.uiState.collectAsState()
...
HomeList(
modifier = Modifier
.padding(it)
.navigationBarsPadding(),
dataList = uiState.homeList,
listState = listState,
onClickItem = { data ->
...
},
onLongPressItem = {
...
}
)
ViewModel 將從 Room 數據庫中加載數據並根據當前屏幕類型過濾不感興趣的數據:
data class HomeUiState(
val homeType: HomeType,
val homeList: List<Data>
)
enum class HomeType {
CREATED,
VIEWED,
STARRED,
ARCHIVED
}
...
viewModelScope.launch(Dispatchers.IO) {
repository.getAllDataFlow().collect { newList ->
Log.d(TAG, "collect new list: $newList")
when (_uiState.value.homeType) {
HomeType.CREATED -> _uiState.update { it.copy(homeList = homeList.filter { data -> data.status == MarkdownData.STATUS_INTERNAL }) }
HomeType.VIEWED -> _uiState.update { it.copy(homeList = homeList.filter { data -> data.status == MarkdownData.STATUS_EXTERNAL }) }
HomeType.STARRED -> _uiState.update { it.copy(homeList = homeList.filter { data -> data.isStarred == MarkdownData.IS_STARRED }) }
HomeType.ARCHIVED -> _uiState.update { it.copy(homeList = homeList.filter { data -> data.status == MarkdownData.STATUS_ARCHIVED }) }
}
}
}
這是我的問題:每次我在 Room 數據庫中刪除一個數據 object 時,流程都會發出新值(刪除后的數據列表),該值被收集並用於更新 Ui State 以進行重組。 日志和實驗表明確實如此:viewModel 收集新列表,然后lazyColumn 觀察新列表並使用items
語法創建可組合項目,並從 UI 中明顯刪除已刪除的項目。
然而,盡管使用新的數據列表進行了重組,但每個可組合項的數據 object 仍然是舊的,並且沒有按預期更新。 例如,如果我有 a、b、c、d 的列表。 刪除a后,列表應該是b,c,d。 UI中顯示的列表確實代表b,c,d,但它們的實際值對應舊的a,b,c,這阻礙了進一步的操作。 但是如果我刷新屏幕(重新啟動應用程序或導航到其他屏幕然后彈出),一切都會恢復正常。
我想知道我是否錯過了任何導致lazyColumn 項目更新UI 但不更新每個項目的實際數據的東西。 謝謝!
我認為需要在下面的LazyColumn
項目中添加鍵,這將有助於將項目識別為一種獨特的方式。
LazyColumn(
modifier = modifier,
state = listState
) {
items(dataList,
key = { listItem ->
listItem.id // or any other unique
})
{ data ->
Log.d(TAG, "HomeList: add data $data")
HomeListItem(
data = data,
onClick = onClickItem,
onLongPressed = onLongPressItem
)
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.