Issue
I'm using Jetpack Compose to implement my requirement of drawing a 'Gradual growing line', i.e a line that starts from a specified start and point and gradually 'grows' until it reaches a specified end point. I had earlier implemented this with Custom view which worked fine. My logic requires the 'onDraw()' to be re-called again and again based on some condition. For this, I had used 'invalidate()' while using Custom view. But now I'm using Jetpack Compose and unable to find a way to recompose 'Canvas'.
Here is my Jetpack compose code for 'gradual growing line':
@Composable
fun SplashUI() {
var test = remember { mutableStateOf(0) }
Canvas(modifier = Modifier.fillMaxSize()) {
// starting point
x1 = 0.0;
y1 = size.height / 2.0;
// ending point
x2 = size.width.toDouble()
y2 = size.height / 2.0;
divideLineIntoEqualParts();
if (test.value < listOfPoints.size) {
drawLine(
Color.Black,
Offset(
listOfPoints.get(0)?.x!!,
listOfPoints.get(0)?.y!!
),
Offset(
listOfPoints.get(inte)?.x!!,
listOfPoints.get(inte)?.y!!
),
strokeWidth = 5f
);
}
test.value = test.value + 1 //This doesn't trigger recomposition of canvas
//Recomposition of Canvas should happen after the above step for my logic to work
//I had implemented this earlier using custom view, and used 'invalidate()' like:
/* if (inte < listOfPoints.size) {
invalidate()
}*/
}
}
private fun divideLineIntoEqualParts() {
listOfPoints.clear()
for (k in 1..50) {
listOfPoints.add(PointF((x1 + k * (x2 - x1) / 50).toFloat(),
(y1 + k * (y2 - y1) / 50).toFloat()
))
}
Log.d("listOfPoints : size : ", listOfPoints.size.toString() + "")
}
Please suggest a way I can recompose Canvas, or some other way to make my logic work.
Solution
There are some differences.
The code in the question works in an Android View, and you are drawing on the Canvas in the onDraw method. You are drawing an horizontal line dividing the available space (=width) in points.
In Compose you are just using a Canvas as a Composable, and you can animate the length of the line.
Something like:
//Animation - it will be repeated 2 times
val animatedProgress = remember { Animatable(0.001f) }
LaunchedEffect(animatedProgress) {
animatedProgress.animateTo(1f,
animationSpec = repeatable(2,
animation = tween(durationMillis = 3000, easing = LinearEasing)
))
}
Canvas(modifier = Modifier.fillMaxSize() ) {
val startingPoint = Offset(0f, size.height / 2f)
val endingPoint = Offset(size.width * animatedProgress.value, size.height / 2f)
//At the end of animation just remove the line
if (animatedProgress.isRunning) {
drawLine(
strokeWidth = 8.dp.toPx(),
color = Color.Black,
start = startingPoint,
end = endingPoint
)
}
}
Answered By - Gabriele Mariotti

0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.