我正在使用 ViewModel 来存储数据。 ViewModel 有一个包含用户列表的 StateFlow 类。还有一个 donut:Int 字段。
在 Compose 中,当我单击“ donut ”按钮时,变量“ donut ”就会递增,并且重组成功 - 按钮“ donut ”上的数据立即发生变化。 在“用户”按钮上,当我单击时,“用户”列表中的数据会更改(通过 logcat 查看),但不会发生重组。但如果之后我按下 donut 按钮,那么屏幕上的用户数据会立即更改为更改后的数据。
我的MainViewModel:
class MainViewModel() : ViewModel() {
private var _usersClass = MutableStateFlow(UsersClass())
val usersClass: StateFlow<UsersClass> = _usersClass.asStateFlow()
fun addDonut(int: Int) {
_usersClass.update {
it.copy(
donuts = int
)
}
}
fun addAgeForAll(){
val newList = _usersClass.value.userList
newList.value.forEach(){a->a.addAge()}
_usersClass.update{
it.copy(
userList = newList
)
}
}
}
我的用户类:
data class UsersClass(
var donuts: Int = 0,
private var _userList: MutableStateFlow<MutableList<User>> = MutableStateFlow(initData.items.toMutableList()),
var userList: StateFlow<List<User>> = _userList.asStateFlow()
)
data class User(
var username: String = "John Doe",
var age: Int = 18
) {
fun addAge() {
age++
}
}
object initData {
var items = arrayListOf(
User(username = "Elvis", age = 18),
User(username = "Sunny", age = 19),
User(username = "Mary", age = 18)
)
}
主要事件:
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val mainViewModel = ViewModelProvider(this)[MainViewModel::class.java]
setContent {
MainScreen(
mainViewModel = mainViewModel,
onClickButtonAddDonut = {
mainViewModel.addDonut(mainViewModel.usersClass.value.donuts + 1)
}
)
}
}
}
@Composable
fun MainScreen(
mainViewModel: MainViewModel,
onClickButtonAddDonut: () -> Unit,
) {
val class1 = mainViewModel.usersClass.collectAsState()
Column {
LazyColumn {
itemsIndexed(class1.value.userList.value) { _, item ->
Button(
onClick = { mainViewModel.addAgeForAll() }
) {
Text(text = item.toString())
}
}
}
Button(
modifier = Modifier,
onClick = { onClickButtonAddDonut() },
content = {
Text(text = "donuts= ${class1.value.donuts}")
})
}
}
为什么重组没有发生?我究竟做错了什么?我一周都搞不明白:( 谢谢
最佳答案
问题就在这里
fun addAge() {
age++
}
这不会通知 Compose 有任何更改,因为它直接改变 age
的值。
一般来说,通过状态流发送的数据应该是不可变的。为此,您可以将 User
更改为,
data class User(
val username: String = "John Doe",
val age: Int = 18
)
和UserClass
是,
data class UsersClass(
val donuts: Int = 0,
val userList: List<User> = emptyList()
)
请注意使用 val
而不是 var
。
经过这些更改,模型上的方法可以是,
fun addAgeForAll(){
val newList = _usersClass.value.userList.map {
it.copy(age = it.age + 1)
}
_usersClass.update{
it.copy(
userList = newList
)
}
}
我建议您保持模型简单,就像这样,直到您知道需要额外的流程来防止跳帧。
关于kotlin - Jetpack Compose - 重组时遇到问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76529606/