带有 LiveData 和 MutableList 的 ViewModel 未在 Jetpack Compose 中更新
ViewModel with LiveData and MutableList not Updating in Jetpack Compose
我是 Android 总体开发的新手,尤其是 Jetpack Compose 及其更新可组合项的方法。我有一个 iOS 背景,但有很多 SwiftUI。
无论如何,我有以下应用程序
可组合项如下所示:
@Composable
fun Greeting() {
Column(
modifier = Modifier
.fillMaxHeight()2
.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.SpaceEvenly
) {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceEvenly
) {
IncrementButton()
DecrementButton()
}
PressedText()
SizeText()
}
}
@Composable
fun PressedText() {
val myViewModel: MyViewModel = viewModel()
val myNumber by myViewModel.number.observeAsState()
Text(text = "Pressed: $myNumber")
}
@Composable
fun SizeText() {
val myViewModel: MyViewModel = viewModel()
val myList by myViewModel.list.observeAsState()
Text(text = "Size: ${myList?.size}")
}
@Composable
fun IncrementButton() {
val myViewModel: MyViewModel = viewModel()
Button(onClick = myViewModel::add) {
Text("Add")
}
}
@Composable
fun DecrementButton() {
val myViewModel: MyViewModel = viewModel()
Button(onClick = myViewModel::remove) {
Text("Remove")
}
}
我使用的视图模型如下所示:
class MyViewModel : ViewModel() {
private val _number = MutableLiveData<Int>()
val number: LiveData<Int> = _number
private val _list = MutableLiveData<MutableList<Int>>()
val list: LiveData<MutableList<Int>> = _list
init {
_number.value = 0
_list.value = mutableListOf()
}
fun add() {
_number.value = _number.value?.plus(1)
_number.value?.let {
_list.value?.add(it)
_list.value = _list.value
}
}
fun remove() {
_number.value = _number.value?.minus(1)
if (_list.value?.isNotEmpty() == true) {
_list.value?.removeAt(0)
_list.value = _list.value
}
}
}
当我按下“添加”按钮时,“按下”后的数字会更新,但“大小”后的数字不会更新。
我真的不确定我从其他 SO post 那里得到的那些带有 _list.value = _list.value
的行,据说要更新列表的引用。
我错过了什么?非常感谢任何提示。
欢迎留下任何关于代码设计的意见。
谢谢!
这个 _list.value = _list.value
真是个坏主意。根据底层实现,它可能有效也可能无效。在这种情况下,它可能是通过指针进行比较的,这就是它不会触发重组的原因。
查看 Why is immutability important in functional programming。
安全的方法是使用非可变列表:
private val _list = MutableLiveData<List<Int>>()
然后像这样改变它:
_list.value = _list.value?.toMutableList()?.apply {
add(value)
}
通过这样做,您每次都会创建一个新列表,这将毫无问题地触发重组。
此外,根本不需要使用 LiveData
:如果您没有某些依赖项,这会让您使用它,您可以选择 Compose 可变状态:它更简洁:
var number by mutableStateOf(0)
private set
private val _list = mutableStateListOf<Int>()
val list: List<Int> = _list
fun add() {
number++
_list.add(number)
}
fun remove() {
number--
_list.removeAt(0)
}
我是 Android 总体开发的新手,尤其是 Jetpack Compose 及其更新可组合项的方法。我有一个 iOS 背景,但有很多 SwiftUI。
无论如何,我有以下应用程序
可组合项如下所示:
@Composable
fun Greeting() {
Column(
modifier = Modifier
.fillMaxHeight()2
.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.SpaceEvenly
) {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceEvenly
) {
IncrementButton()
DecrementButton()
}
PressedText()
SizeText()
}
}
@Composable
fun PressedText() {
val myViewModel: MyViewModel = viewModel()
val myNumber by myViewModel.number.observeAsState()
Text(text = "Pressed: $myNumber")
}
@Composable
fun SizeText() {
val myViewModel: MyViewModel = viewModel()
val myList by myViewModel.list.observeAsState()
Text(text = "Size: ${myList?.size}")
}
@Composable
fun IncrementButton() {
val myViewModel: MyViewModel = viewModel()
Button(onClick = myViewModel::add) {
Text("Add")
}
}
@Composable
fun DecrementButton() {
val myViewModel: MyViewModel = viewModel()
Button(onClick = myViewModel::remove) {
Text("Remove")
}
}
我使用的视图模型如下所示:
class MyViewModel : ViewModel() {
private val _number = MutableLiveData<Int>()
val number: LiveData<Int> = _number
private val _list = MutableLiveData<MutableList<Int>>()
val list: LiveData<MutableList<Int>> = _list
init {
_number.value = 0
_list.value = mutableListOf()
}
fun add() {
_number.value = _number.value?.plus(1)
_number.value?.let {
_list.value?.add(it)
_list.value = _list.value
}
}
fun remove() {
_number.value = _number.value?.minus(1)
if (_list.value?.isNotEmpty() == true) {
_list.value?.removeAt(0)
_list.value = _list.value
}
}
}
当我按下“添加”按钮时,“按下”后的数字会更新,但“大小”后的数字不会更新。
我真的不确定我从其他 SO post 那里得到的那些带有 _list.value = _list.value
的行,据说要更新列表的引用。
我错过了什么?非常感谢任何提示。
欢迎留下任何关于代码设计的意见。
谢谢!
这个 _list.value = _list.value
真是个坏主意。根据底层实现,它可能有效也可能无效。在这种情况下,它可能是通过指针进行比较的,这就是它不会触发重组的原因。
查看 Why is immutability important in functional programming。
安全的方法是使用非可变列表:
private val _list = MutableLiveData<List<Int>>()
然后像这样改变它:
_list.value = _list.value?.toMutableList()?.apply {
add(value)
}
通过这样做,您每次都会创建一个新列表,这将毫无问题地触发重组。
此外,根本不需要使用 LiveData
:如果您没有某些依赖项,这会让您使用它,您可以选择 Compose 可变状态:它更简洁:
var number by mutableStateOf(0)
private set
private val _list = mutableStateListOf<Int>()
val list: List<Int> = _list
fun add() {
number++
_list.add(number)
}
fun remove() {
number--
_list.removeAt(0)
}