Eyn*_*err 1 android android-jetpack-compose
我有一个lazyColumn从viewModel接收列表来创建项目:
@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
)
}
}
}
Run Code Online (Sandbox Code Playgroud)
该列表包装在 viewModel 中的 stateFlow 中,并在 Composable 中收集为状态:
// viewModel
...
private val _uiState = MutableStateFlow(
HomeUiState(
...
homeList = listOf()
)
)
val uiState = _uiState as StateFlow<HomeUiState>
...
Run Code Online (Sandbox Code Playgroud)
// HomeScreen
val uiState by viewModel.uiState.collectAsState()
...
HomeList(
modifier = Modifier
.padding(it)
.navigationBarsPadding(),
dataList = uiState.homeList,
listState = listState,
onClickItem = { data ->
...
},
onLongPressItem = {
...
}
)
Run Code Online (Sandbox Code Playgroud)
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 }) }
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的问题:每次我删除 Room 数据库中的 Data 对象时,流程都会发出新值(删除后的数据列表),该值被收集并用于更新 Ui State 以进行重组。日志和实验表明确实如此:viewModel 收集新列表,然后lazyColumn 观察新列表并使用items语法创建可组合项,删除的项会从 UI 中明显删除。
然而,尽管使用新的数据列表进行重组,每个可组合项的数据对象仍然是旧的,并且不会按预期更新。例如,如果我有 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
)
}
}
Run Code Online (Sandbox Code Playgroud)
在这里查看更多关于键在列表中如何有用的信息:https://developer.android.com/jetpack/compose/lists#item-keys
另外 key 如何帮助重组:https://developer.android.com/jetpack/compose/lifecycle#add-info-smart-recomposition
| 归档时间: |
|
| 查看次数: |
3862 次 |
| 最近记录: |