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.