为什么 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 的优点,摒弃丑陋的遗留垃圾。
在 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 的优点,摒弃丑陋的遗留垃圾。