带有 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)
}