You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Kotlin/Jetpack Compose中通过ViewModel更新ByteArray与列表UI?

问题分析与解决方案

核心原因

mutableStateOf 对引用类型(比如ByteArray、List)的更新检测,依赖于引用本身的变化。如果只是修改数组/列表的内部元素(比如改ByteArray的某个字节、给mutableList加元素),对象引用没改变,Compose就检测不到状态变化,自然不会触发UI重组。而Float是值类型,修改值就会触发状态更新,所以能正常工作。

针对ByteArray的解决方案

不要直接修改现有ByteArray的元素,而是创建新的数组实例赋值给状态变量:

// ViewModel中更新ByteArray的正确方式
fun updateByteArray(index: Int, value: Byte) {
    val newData = Data.copy() // 复制原数组
    newData[index] = value    // 修改新数组的元素
    Data = newData            // 赋值新数组,触发状态更新
}

针对列表的解决方案

有两种可选方式:

  1. 用mutableStateListOf()替代mutableStateOf(mutableListOf()),这是Compose专门提供的可变状态集合,会自动跟踪元素的增删改,无需替换整个列表引用:
// ViewModel中定义状态列表
val stateList = mutableStateListOf<String>()

// 直接修改元素即可触发UI更新
fun addItem(item: String) {
    stateList.add(item)
}
  1. 若坚持用mutableStateOf包裹列表,每次修改后要生成新的列表实例赋值:
var stateList by mutableStateOf(mutableListOf<String>())

fun addItem(item: String) {
    stateList = stateList.toMutableList().apply { add(item) }
}

额外修正:ViewModel的错误用法

你当前用companion object创建shared单例的方式不符合ViewModel的生命周期规范,会导致内存泄漏。正确的做法是在Composable中通过viewModel()函数获取实例:

// Composable中获取ViewModel
val viewModel: BluetoothMonitoring = viewModel()
val data = viewModel.Data

内容的提问来源于stack exchange,提问作者Swifty

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 19:15:28