I'm currently trying to work on an app that involves data coming from WearOS watches to an Android phone. When it gets to the phone, I'd like to chart the data (I'm currently trying to use MP Android Chart for this).
I'm using mutableStateListOf to attempt to watch changes to this list, as shown below:
private val repDataPoints = mutableStateListOf<RepDataPoint>()
RepDataPoint is a data class containing an x value and a boolean.
I send the data from the watch all at once, after it is done being collected. Then, I add it to this list. This appears to be working, as logcat in Android Studio shows the list is not staying at size 0. That code is here:
override fun onDataChanged(dataEvents: DataEventBuffer) {
for (event in dataEvents) {
if (event.type == DataEvent.TYPE_CHANGED && event.dataItem.uri.path == "/sensor_data") {
//Keys are x, values are "isRep"
val dataMapItem = DataMapItem.fromDataItem(event.dataItem)
val dataPoints = dataMapItem.dataMap.getDataMapArrayList("dataPoints")
//Debug - did we get the data?
Log.d("PhoneApp", "Data received with ${dataPoints?.size} data points")
dataPoints?.forEach { dataMap ->
val x = dataMap.getFloat("x")
val isRep = dataMap.getBoolean("isRep")
//Debug - what points did we get?
Log.d("PhoneApp", "Received data - X: $x, isRep: $isRep")
repDataPoints.add(RepDataPoint(x, isRep))
}
}
}
}
Here's where I want to use the data, in a composable that will hopefully show the graph:
@Composable
fun LineChartCompose(data: List<RepDataPoint>) {
AndroidView(factory = { context ->
LineChart(context).apply {
// Log the size of the data list
Log.d("LineChartCompose", "Data size: ${data.size}")
val entries = data.mapIndexed { index, point ->
Log.d("LineChartCompose", "Data point: index=$index, x=${point.x}, isRep=${point.isRep}")
Entry(index.toFloat(), point.x)
}
val dataSet = LineDataSet(entries, "Data").apply {
color = Color.BLUE
valueTextColor = Color.BLACK
setDrawValues(false)
setDrawCircles(true)
circleRadius = 4f
setCircleColor(Color.BLUE)
circleHoleColor = Color.BLUE
}
val lineData = LineData(dataSet)
this.data = lineData
description.isEnabled = false
setTouchEnabled(true)
isDragEnabled = true
setScaleEnabled(true)
setPinchZoom(true)
axisRight.isEnabled = false
xAxis.position = XAxis.XAxisPosition.BOTTOM
Log.d("LineChartCompose", "Chart invalidated")
invalidate()
}
})
}
These log statements only show up once, at the app's creation (which currently only shows this composable), with a list size of 0. I've tried reading up on mutableStateListOf, but everything I'm seeing says that adding to the list would qualify as modifying it, which would notify any composables that rely on it (like this one). The only thing I'm not sure about is that the documents say that those composables must also read the values, but I think I'm doing that here.
The list at the end of onDataChanged was 92 elements long, but still, no change was triggered. I'm still pretty new to Android. Am I making some stupid mistake? Is there a way I could reorganize my data to make better sure the composable starts drawing a graph when it gets data?
Any help is appreciated, and being new, any advice on how to write my code better is also welcome!
I sent data from the watch, logged it as it got to the phone, and made sure the list was being modified. Recomposition does not appear to be occurring, so I'm not getting a graph to draw.
repDataPoints
? In a ViewModel?