更新到 viewModel 后视图未更新

问题描述 投票:0回答:1

我有下面的项目列表,每个项目旁边都有一个按钮形式的复选框。 当未选择该按钮时,应显示一个黑色空圆圈。 选择按钮后,黑色圆圈内应该有一个复选标记。

通过运行代码并查看调试日志,视图模型正在更新,但我的视图没有更新。 缺少什么?

data class ListItem(
    var title: String,
    var checked: Boolean
)



class ItemsViewModel: ViewModel() {

    private var _reportDetails: MutableStateFlow<MutableList<String>> = MutableStateFlow(mutableListOf())
    val reportDetails = _reportDetails.asStateFlow()


    private var _issues: MutableStateFlow<MutableList<ListItem>> =
        MutableStateFlow(mutableListOf(
            ListItem(title = "Item 1", checked = false),
            ListItem(title = "Item 2", checked = false),
            ListItem(title = "Item 3", checked = false),
            ListItem(title = "Item 4", checked = false),
            ListItem(title = "Item 5", checked = false),
            ListItem(title = "Item 6", checked = false),
            ListItem(title = "Item 7", checked = false),
            ListItem(title = "Item 8", checked = false),
            ListItem(title = "Item 9", checked = false)
        ))
    val issues = _issues.asStateFlow()


    fun addToReportDetails(reportDetail: String) {
        _reportDetails.update {
            it.add(reportDetail)
            return
        }
    }

    fun removeFromReportDetails(reportDetail: String) {
        _reportDetails.update {
            it.remove(reportDetail)
            return
        }
    }


    fun updateOnlineIssuesAtIndex(index: Int, checked: Boolean) {
        _issues.update {
            it[index].checked = checked
            return
        }
    }

}



@Composable
fun ReportView(
    itemsViewModel: ItemsViewModel,
) {

    val reportDetails by itemsViewModel.reportDetails.collectAsStateWithLifecycle()
    val issues by itemsViewModel.issues.collectAsStateWithLifecycle()


    LazyColumn(
        modifier = Modifier
            .padding(50.dp)
    ) {

        item {

            for ((index, issue) in issues.withIndex()) {
                Column(
                    verticalArrangement = Arrangement.spacedBy(5.dp),
                ) {

                    Row(
                        verticalAlignment = Alignment.CenterVertically,
                        horizontalArrangement = Arrangement.spacedBy(10.dp)
                    ) {

                        Text(text = issue.title)

                        Button(
                            onClick = {
                                if (!issue.checked) {
                                    itemsViewModel.updateOnlineIssuesAtIndex(index = index, checked = true)
                                    itemsViewModel.addToReportDetails(issue.title)
                                    Log.d("ReportUser", "reportDetails = $reportDetails")
                                    Log.d("ReportUser", "issue.checked = ${issue.checked}")
                                } else {
                                    itemsViewModel.updateOnlineIssuesAtIndex(index = index, checked = false)
                                    itemsViewModel.removeFromReportDetails(issue.title)
                                    Log.d("ReportUser", "reportDetails = $reportDetails")
                                    Log.d("ReportUser", "issue.checked = ${issue.checked}")
                                }
                            }
                        ) {
                            Box(
                                modifier = Modifier
                                    .size(25.dp)
                                    .border(
                                        width = 1.dp,
                                        color = Color.Black,
                                        shape = CircleShape
                                    )
                            ) {
                                if (issue.checked) {
                                    Icon(
                                        imageVector = Icons.Rounded.CheckCircle,
                                        contentDescription = "null",
                                        modifier = Modifier.size(25.dp),
                                        tint = Color.Black,
                                    )
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
mvvm android-jetpack-compose viewmodel android-viewmodel
1个回答
0
投票

您的 MutableList 必须是不可变的,否则 Stateflow 无法检测到更改:

class ItemsViewModel : ViewModel() {
    private var _reportDetails: MutableStateFlow<List<String>> = MutableStateFlow(emptyList())
    val reportDetails = _reportDetails.asStateFlow()

    private var _issues: MutableStateFlow<List<ListItem>> =
        MutableStateFlow(
            listOf(
                ListItem(title = "Item 1", checked = false),
                ListItem(title = "Item 2", checked = false),
                ListItem(title = "Item 3", checked = false),
                ListItem(title = "Item 4", checked = false),
                ListItem(title = "Item 5", checked = false),
                ListItem(title = "Item 6", checked = false),
                ListItem(title = "Item 7", checked = false),
                ListItem(title = "Item 8", checked = false),
                ListItem(title = "Item 9", checked = false),
            ),
        )
    val issues = _issues.asStateFlow()

    fun addToReportDetails(reportDetail: String) {
        _reportDetails.update {
            it + reportDetail
        }
    }

    fun removeFromReportDetails(reportDetail: String) {
        _reportDetails.update {
            it - reportDetail
        }
    }
}

出于同样的原因,

ListItem
也必须是不可变的:

data class ListItem(
    val title: String,
    val checked: Boolean,
)
fun updateOnlineIssuesAtIndex(
    index: Int,
    checked: Boolean,
) {
    _issues.update {
        it.mapIndexed { itemIndex, item ->
            if (itemIndex == index) item.copy(checked = checked)
            else item
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.