I'm currently working on a Jetpack Compose
project where I've implemented a custom chart using the Canvas
API. I'm utilizing a MutableStateFlow<List<Offset>?>
to represent a list of points that I draw on the Canvas. The drawing logic is handled within the Canvas Composable.
I've encountered an issue when I set the list of points to null in my ViewModel
using _points.emit(null)
. Despite setting the points to null, the Canvas does not seem to understand that it should clear the previously drawn content.
Here's a simplified version of the relevant code:
private val _points = MutableStateFlow<List<Offset>?>(null)
val points: StateFlow<List<Offset>?>
get() = _points
private fun updatePoints() = uiEventScope.launch {
val pointList = ArrayList<Offset>()
// Some logic to populate the list...
_points.emit(pointList)
}
private fun removePoints() = uiEventScope.launch {
// Some logic to clear the list or set it to null...
_points.emit(null)
}
val points by viewModel.points.colectAsState()
Canvas(
modifier = Modifier.fillMaxSize()
) {
points?.apply {
for (i in 0 until points.size - 1) {
// Drawing logic...
}
}
}
I expected that setting the points to null would clear the Canvas, but it seems like the previous content persists. I would appreciate any insights into why this might be happening and how I can ensure that the Canvas clears its content when the StateFlow
is set to null.
Thank you for your help!
We need to handle the case where the list is null. I added an empty rect with a background color when it is null. You can change this however you want. But you need to handle the situation where null is returned with a logic similar to this. You didn't add where you collected the flow. If you are not using collectAsState
you may need to adapt this logic where you collect.
val backgroundColor = MaterialTheme.colorScheme.background
Canvas(
modifier = Modifier
.fillMaxSize()
.drawBehind {
if (points.value == null) {
drawRect(backgroundColor, size = size)
return@drawBehind
}
points.value?.let { pointList ->
for (i in 0 until pointList.size - 1) {
// Drawing logic...
}
}
}
) {
}