What do I want to achieve?
I want to create the following layout. It is important that the vertical "connecting" lines go inside the numbered boxes:
What did I already try (first, naive approach)?
I created the layout using a composable and a few lines. The numbered boxes get a boolean parameter which indicate if the top or bottom lines inside the box are shown. There also are vertical lines between the composables which draw the vetical lines. It produces the expected result and renders this image:
This is the code I used:
@Composable
fun ConnectedComposable(modifier: Modifier) {
Column(modifier = modifier) {
NumberedBox(
number = 1,
topLine = false,
bottomLine = true
)
VerticalDivider(Modifier.height(64.dp))
NumberedBox(
number = 2,
topLine = true,
bottomLine = true
)
VerticalDivider(Modifier.height(64.dp))
NumberedBox(
number = 3,
topLine = true,
bottomLine = false
)
}
}
@Composable
fun ColumnScope.VerticalDivider(
modifier: Modifier = Modifier
) {
Divider(
modifier = modifier
.width(2.dp)
.align(Alignment.CenterHorizontally),
color = Color.Black
)
}
@Composable
fun NumberedBox(
number: Int,
topLine: Boolean,
bottomLine: Boolean,
modifier: Modifier = Modifier
) {
Surface(
color = Color.LightGray,
border = BorderStroke(1.dp, Color.Black),
modifier = modifier
.size(100.dp)
.fillMaxSize()
) {
Column(
modifier = Modifier
.padding(horizontal = 16.dp)
.fillMaxSize()
) {
if (topLine) {
VerticalDivider(
Modifier.weight(1f)
)
}
else {
Spacer(modifier = Modifier.weight(1f))
}
Text(
number.toString(),
modifier = Modifier
.align(Alignment.CenterHorizontally)
.padding(vertical = 16.dp),
textAlign = TextAlign.Center
)
if (bottomLine) {
VerticalDivider(
Modifier.weight(1f)
)
}
else {
Spacer(modifier = Modifier.weight(1f))
}
}
}
}
@Preview
@Composable
fun ConnectedComposable_Preview() {
Scaffold {
ConnectedComposable(
Modifier
.padding(it)
.padding(16.dp)
)
}
}
My question
I do not like the above code because of these points:
- It is hard to maintain if the layout changes in the future
- It gets more complex if the size of the
NumberedBox
is not fixed - The code to calculate the line positions inside and outside the box must be kept in sync
- The positioning code may not be trivial if the lines are not centered.
Is there a different/better way to archieve this layout?