我有下面的项目列表,每个项目旁边都有一个按钮形式的复选框。 当未选择该按钮时,应显示一个黑色空圆圈。 选择按钮后,黑色圆圈内应该有一个复选标记。
通过运行代码并查看调试日志,视图模型正在更新,但我的视图没有更新。 缺少什么?
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,
)
}
}
}
}
}
}
}
}
}
您的 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
}
}
}