Jetpack Compose:动态添加条目到 MPAndroidCharts 时出现 UnsupportedOperationException

Jetpack Compose: UnsupportedOperationException when adding Entries to MPAndroidCharts dynamically

我尝试在 AndroidView 中托管的 MPAndroidChart 中显示实时数据。

我得到了图表,但是当我调用 addEntry() 动态更新图表时发生 UnsupportedOperationException。我做错了什么吗?

您在评论中找到了一个演示存储库。

@Composable
fun MyLineChart() {
    val mainViewModel = viewModel()
    val sensorData = mainViewModel.sensorFlow.collectAsState(SensorModel(0F,0F)).value

    AndroidView(modifier = Modifier.fillMaxSize(),
        factory = { context ->
            val lineChart = LineChart(context)
            var entries = listOf(Entry(1f,1f))

            val dataSet = LineDataSet(entries, "Label").apply { color = Color.Red.toArgb() }

            val lineData = LineData(dataSet)
            lineChart.data = lineData
            lineChart.invalidate()

            lineChart
        }){

        try {
            Log.d("TAG", "MyLineChart: Update --- Current thread id: ${Thread.currentThread()}")

            it.data.dataSets[0].addEntry(Entry(sensorData.x, sensorData.y))
            it.lineData.notifyDataChanged()
            it.notifyDataSetChanged()
            it.invalidate()
        } catch(ex: Exception) {
            Log.d("TAG", "MyLineChart: $ex")
        }
    }
}

数据通过以下ViewModel发送到视图:

@HiltViewModel
class MainViewModel @Inject constructor(@ApplicationContext var appContext: Context) : ViewModel()  {
    private var rand: Random = Random(1)

    val sensorFlow: Flow<SensorModel> = flow<SensorModel> {

        while (true) {
            delay(1000L)
            Log.d("TAG", "sensorFlow: Current thread id: ${Thread.currentThread()}")
            emit(SensorModel(rand.nextFloat(), rand.nextFloat()))
        }
    }
}

试试这个代码:

        // it.data.dataSets[0].addEntry(Entry(sensorData.x, sensorData.y))
        
        val entryList =  mutableListOf<Entry>()            
        entryList.add(Entry(sensorData.x, sensorData.y))
        
        val dataSet = LineDataSet(entryList, "Label").apply {
            color = Color.Red.toArgb()
        }
        
        it.data = LineData(dataSet)

您将 entries 传递给 LineDataSet,这是一个不可变列表。

这个库似乎有一个很糟糕的地方API,因为它不要求将可修改的列表作为参数,但同时又不使其本身可修改。这会导致您尝试修改不可变列表,从而导致异常。

替换

var entries = listOf(Entry(1f,1f))

val entries = mutableListOf(Entry(1f,1f))

p.s。我不能建议你使用另一个图形库,因为我没有使用过任何图形库,但我建议你寻找一个更好的库 API.