![](/img/trans.png)
[英]java.lang.IllegalStateException when using State in Android Jetpack Compose
[英]Handling state using list in android Jetpack compose
我正在嘗試更新一個列表,該列表保留為可組合視圖的 state,但即使列表的值已更改,可組合視圖也不會重新組合。
var list = remember {mutableStateOf(getListOfItems())}
ItemListView({ selectedItem ->
list.value = updateList(selectedItem, list.value)
}, list.value)
private fun updateList(selectedItem: String,
itemsList: List<Product>): List<Product> {
for (item in itemsList){
// selected item in the view is updated
item.selected = item.name == selectedItem
}
return itemsList
}
知道為什么可組合組件沒有更新嗎? 我注意到當使用列表作為 state 時會發生此問題。
您需要更新MutableState
的value
(在您的示例中是一個List
),以觸發重組,而不是您設置為MutableState
的任何值屬性。
@Stable
interface MutableState<T> : State<T> {
override var value: T
operator fun component1(): T
operator fun component2(): (T) -> Unit
}
但是還有另一個名為mutableStateListOf()
的 function 可以在您添加或刪除項目或使用新實例更新現有項目時觸發重組。
val list =remember {
mutableStateListOf< Product>().apply {
addAll(getListOfItems())
}
}
jetpack compose 會查看您的 object 本身,看看它是否已更改以決定是否更新它。 您需要更新列表本身才能做到這一點:
data class A(var v: Int)
@Composable
fun Test1() {
var list by remember { mutableStateOf(listOf(A(1), A(2), A(3))) }
LazyColumn(modifier = Modifier.fillMaxSize()) {
items(list) {
Text(text = it.toString())
}
item {
// it does not work
Button(onClick = {
list[0].v = 2
}) { Text("Change value") }
// it works
Button(onClick = {
list = list.map { it.copy(v = it.v + 1) }
}) { Text("Change list") }
}
}
}
此外,您可以使用 mutableStateListOf,它會監視元素的添加和刪除。
@Composable
fun Test2() {
val list = remember { mutableStateListOf(A(1), A(2), A(3)) }
LazyColumn(modifier = Modifier.fillMaxSize()) {
items(list) {
Text(text = it.toString())
}
item {
// it not work
Button(onClick = {
list[0].v = 2
}) { Text("Change value") }
// it work
Button(onClick = {
list.add(A(3))
}) { Text("Change list") }
}
}
}
在您的情況下,您可以像這樣表示選擇:
val selectedList = remember { mutableStateListOf<String>() }
LazyColumn(modifier = Modifier.fillMaxSize()) {
items(list) {
val selected = selectedList.contains(it.name)
Text(text = if (selected) "selected" else "not selected")
Button(onClick = {
if (!selected) selectedList.add(it.name)
}) { Text("Select it") }
}
}
通過獲取具有新值的列表副本來解決此問題:
private fun updateList(selectedItem: String,
itemsList: List<Product>): List<Product> {
val updatedList = itemsList.map { product ->
if(product.name == selectedItem) {
product.copy(selected = true)
} else {
product.copy(selected = false)
}
}
return updatedList
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.