为什么 Jetpack Compose LazyColumn MutableLiveData 仅在第一次单击按钮时重新组合?

Why does Jetpack Compose LazyColumn MutableLiveData only recompose on first button click?

在 Android Studio 中学习 Kotlin 和 Jetpack Compose。试图理解重组。

以下代码仅在第一次单击按钮时重新组合 - 为什么?

输出显示在我的代码下方。基本上,我第一次单击“添加新项目”按钮时,屏幕会完美地重组,但之后就不会再重组了。 但是,如果您查看 LogCat,您可以看到它仍在工作,只是没有更新屏幕。我错过了什么?

查看模型

class MainViewModel : ViewModel() {
    val listLiveData: LiveData<List<Int>>
        get() = newListLiveData

    private val newList = ArrayList<Int>()
    private val newListLiveData = MutableLiveData<List<Int>>()

    fun addNewListItem(listItem: Int) {
        newList.add(listItem)
        newListLiveData.value = newList
        println("**** addNewListItem($listItem)")
    }
}    

主屏幕支架和内容

@Composable
fun HomeScreen(
    navController: NavHostController,
    model: MainViewModel
) {

    val stuff by model.listLiveData.observeAsState(emptyList())

    Scaffold(
        content = { Content(model, stuff) }
    )

}

@Composable
fun Content(
    model: MainViewModel = MainViewModel(),
    stuff: List<Int>
) {
        LazyColumn() {
            items(items = stuff){ index ->
                Text("$index")
            }
        }
        Button(
            onClick = { model.addNewListItem((0..10).random()) },
        ) {
            Text(text = "Add Random Item to List")
        }
}

LogCat输出

I/System.out: **** addNewListItem(0)  <-- Recomposes fine here 
I/System.out: **** addNewListItem(2)  <-- Does not recompose
I/System.out: **** addNewListItem(5)  <-- Does not recompose
I/System.out: **** addNewListItem(6)  <-- Does not recompose
I/System.out: **** addNewListItem(4)  <-- Does not recompose

截图

谢谢

老实说,只要您不需要与 View 系统进行互操作,请避免使用 built-for-Compose MutableState<T> 对象以外的任何对象。您的 ultra-boilerplate 代码可以简单地替换为

ViewModel{
 val cleanList by mutableStateListOf<Item>() // Initialized as an Empty list of 'Item's
 fun addItem(item: Item){
  cleanList.add
 }
}

在可组合项中,

@Composable
MyComposable(
 list: List<Item>,
 onAddItem: (Item) -> Unit // Receive Item, return Unit
) {
 Button { // This is on-Click, assume
  onAddItem(/*Add Item Here, per logic*/)
 }
}

像这样在任何地方调用它

MyComposable(list = viewModel.cleanList, onAddItem = viewModel::addItem)

这是一些很好的代码。易于阅读,没有样板,令人费解的美丽和干净 crystal。

利用 Compose 的优点,摒弃丑陋的遗留垃圾。