android - 可变列表更改时视图不会重新组合
问题描述
我有一个在视图模型中有一个状态列表的应用程序。我有在列表中添加数字的功能。当我单击一个按钮时,它会在列表中添加数字。但这些变化并没有反映在另一个视图中。
MainActivity.kt
class MainActivity : ComponentActivity() {
private val viewModel by viewModels<MainViewModel>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MyApplicationTheme {
// A surface container using the 'background' color from the theme
Surface(color = MaterialTheme.colors.background) {
Column {
Button(onClick = {viewModel.increaseCounter()}) {
Text("Increase counter")
}
CountView(viewModel.counter)
}
}
}
}
}
}
@SuppressLint("CoroutineCreationDuringComposition")
@Composable
fun CountView(count: List<Int>) {
var coroutineScope = rememberCoroutineScope()
coroutineScope.launch {
Log.d("inside the coroutine ${count}")
}
}
主视图模型.kt
class MainViewModel: ViewModel() {
var counter = mutableStateListOf<Int>()
fun increaseCounter() {
Log.d(">>>", "in viewmodel ${counter.size}")
counter.add(1)
}
}
期望的结果:每当我单击按钮时,必须打印日志,因为它在 mutableStateList 中添加了一个数字。
但是,当我将 mutableStateListOf 更改为 mutableStateOf 并存储一些整数并更改整数时,当我单击按钮时,视图会重新组合并打印日志
解决方案
您的函数未重新组合的主要问题是您没有使用视图本身的值,因此 Compose 缓存它。如果您添加Text(count.joinToString { it.to() })
到您的视图中,它将起作用。
但首先你不应该直接从可组合函数中使用协程。并且添加@SuppressLint("CoroutineCreationDuringComposition")
不是 IDE 向您显示的错误的正确解决方案:
启动调用应该发生在 a
LaunchedEffect
而不是组合内
因此,您的代码应如下所示:
@Composable
fun CountView(count: List<Int>) {
LaunchedEffect(count) {
println("inside the coroutine $count")
}
}
这在您的情况下也不起作用,因为 with mutableStateListOf
,LaunchedEffect
按指针比较键,并且由于这仍然是同一个容器,LaunchedEffect
因此不会重新启动。要通过引用进行比较,传递一个简单的列表会更干净:
CountView(viewModel.counter.toList())
请注意,LaunchedEffect
您已经在协程范围内并且可以运行挂起函数。
rememberCoroutineScope
通常在您需要从其他副作用启动协程时使用,例如按钮单击。
在文档中阅读有关副作用的移动
推荐阅读
- javascript - 从事件中心获取消息到变量
- c++ - Ncurses 和 gdb 屏幕在调试时重叠。所以我想把两个屏幕分开
- java - 使用 Java 文件写入器将文件写入共享驱动器 (NAS) 的权限问题
- ios - 而不是删除一个数组,我希望它将数组发送到另一个 UIViewController
- angular - 在navigateByUrl()时Angular动态路由名称不起作用,需要刷新页面
- laravel - Laravel JWT:无法实现 JWTSubject
- java - 动态 Json 形成
- android - 无法在 android 版本 5.1 上安装 React-native 应用程序
- javascript - Typescript 装饰器可以访问 DEFAULT 参数吗?
- python - pycharm在导入webdrivers时显示错误