Hi guys, I am trying to build a "timeline view" in...
# compose-android
k
Hi guys, I am trying to build a "timeline view" in Compose and I am struggling a bit, details in the comment. Thanks for help.
solved 1
Hi guys (long post warning), I am trying to create a timeline view in jetpack compose and I am facing a problem that I haven't been able to solve for few hours now. The timeline is supposed to look something the illustration in the first pic, with "boxes" with content (which should be whatever, simple text, image,...), nodes (that should be aligned with the middle of the content box) and lines connecting nodes. I have come up with an idea how to build this: I have a list of rows, where each row contains two Box composables. Left Box has weight of 1 and contains timeline node and lines, right Box contains timeline content. In the left Box, I have placed Column (filling max size), in which i draw two lines (two canvases), the first one starting in the center of the box and ending in the middle of the box's top edge (top line) and the second one starting in the center of the box and ending in the middle of the bottom edge (bottom line). On top of those lines, I draw a circle in the middle of the box, that represents timeline node. For the first item in the timeline, I dont draw the top line, for the last item, I dont draw the bottom line. This somewhat works and I am able to easily change state of each timeline row (to open/finished/...) state, as you can see in the second pic. What you can also see though is that when a step in the timeline is "finished", both the top line and bottom line turn green. I only want the top line and the node to be green. I felt like this could be solved easily but that wasn't the case for me (it might in fact be :D). Here's what I have tried: 1. Measure height of a row with onSizeChanged, divide it by two, then pass it outside the timeline row composable with a callback:
Copy code
.onSizeChanged {
    onHeightMeasured((it.height / 2).dp)
}
Outside the timeline row composable, I would save this value to a variable:
Copy code
var boxHeight by remember {
    mutableStateOf(0.dp)
}

onHeightMeasured = {
    boxHeight = it
}
Then, in a LazyColumn, I tried to pass this box height (as in previous box height) to the next timeline row, which I would then use to draw the timeline line. This time, I would only draw one line, starting in the centre of a timeline row left box and ending in the middle of the box's top edge with previous box height substracted:
Copy code
itemsIndexed(steps) { index, step ->
    val previousBoxHeight = boxHeight
    TimelineRow(
        onHeightMeasured = {
            boxHeight = it
        },
        previousBoxHeight = previousBoxHeight

...

drawLine(
    color = Color.Black,
    strokeWidth = 6f,
    start = Offset(size.width / 2, size.height / 2),
    end = Offset(size.width / 2, 0f - previousBoxHeight.toPx())
)
This solution however did not work, items in the list would be placed first, then it would measure its heights and it was a mess overall. Then i tried to somehow access next item in the list and change its color of the top line but i couldn't make it work and it was too hacky. I am not asking for a concrete solution, but if anyone here may know how to solve it (so that nodes are in the middle of the timeline row, lines connect them and are colored as they should), please let me know. Thank you so much.
a
I’m not sure if I understood correctly but why not just draw the top line in green and the bottom line in black for the last finished item?
🙌 1
k
@kecaroh Just giving a quick glance at the screenshot, could you tell each node to check the status of the node before it in order to determine the color of the current node’s top line? For instance, it seems that Task D could check to see that Task C is completed and because it is then draw the top line of Task D green. Finally, because Task D is not completed, draw its circle and bottom line black. Would that work?
🙌 1
k
@Albert Chang @Kevin Worth thanks to both of you, in the end, I implemented the way Kevin suggested and it works fine gratitude danke
😎 1
a
I posted a sample earlier in here iirc
Lemme find it
p
@kecaroh You can checkout my library for creating a timeline view in Compose: https://github.com/pushpalroy/jetlime
116 Views