0

I am using to drawBehind in my Column. I want to draw side by side. I draw line to specific coordinate and want my Text side of it. I tried this code

@Preview(showBackground = true)
@Composable
fun ItemView() {
    val names = listOf("Captain" to "Vice Captain")
    LazyColumn(modifier = Modifier.fillMaxSize()) {
        itemsIndexed(names) { index, item ->

            var titleCoordinates by remember { mutableStateOf<LayoutCoordinates?>(null) }
            Column(
                modifier = Modifier
                    .fillMaxWidth()
                    .drawBehind {
                        val titleBounds = titleCoordinates?.boundsInParent()
                        if (titleBounds != null) {
                            val offset = Offset(x = center.x / 2, y = titleBounds.top)
                            drawLine(
                                color = Color.Black,
                                start = offset,
                                end = offset.copy(y = size.height),
                                strokeWidth = 2.dp.toPx(),
                            )
                        }
                    }
            ) {
                Box(
                    Modifier
                        .padding(top = 24.dp)
                        .onGloballyPositioned { titleCoordinates = it }
                ) {
                    Text(text = item.first, color = Color.Red)
                }
                Text(text = item.second, color = Color.Blue)
            }
        }
    }
}

Actual Output

enter image description here

I can add padding(start = 120.dp) in Column to get my below output. I want to avoid these padding. Is it possible to achieve below output?

Expected Output

enter image description here

Many Thanks

Kotlin Learner
  • 3,995
  • 6
  • 47
  • 127
  • Why do you draw to Column with padding before drawBehind modifier? You can easily draw on left side of both `Text`s if you put them inside a Column – Thracian May 03 '23 at 21:11
  • And you are using center of a Column, for x coordinate , that has fillMaxWidth would return half width of parent which supposed to be as in actual output – Thracian May 03 '23 at 21:13
  • Can you please provide me example for this to fix this problem? – Kotlin Learner May 03 '23 at 21:24
  • I didn't understand what your goal exactly is. Why don't you want to add padding to start and you can add a padding after drawBehind to add another padding after line and before texts – Thracian May 03 '23 at 21:34
  • Do you want content to be placed based on where your line is drawn? If that's the case why do you position line based on Box coordinates? – Thracian May 03 '23 at 21:35
  • Oh yes I fixed the problem by adding padding before of `drawBehind` and after adding a padding.. Thanks great suggestion.. – Kotlin Learner May 03 '23 at 21:38
  • yes content to be placed on where line drawn. How can we do with Box coordinates? – Kotlin Learner May 03 '23 at 21:39
  • By using Modifier.drawWithContent and translating position of drawing and actual content. Second translate is moving actual content from the position line is drawn – Thracian May 03 '23 at 21:43

1 Answers1

2

If you you wish to align drawing with actual Content of a Composable you can use Modifier.drawWithContent{}. drawContent() draws what's inside the Composable that this modifier is assigned to while you can position content and drawing based on each other or other requirements.

enter image description here

@Preview
@Composable
fun ItemView() {
    Column(
        modifier = Modifier
            .fillMaxWidth()
            .padding(20.dp)

    ) {
        val names = listOf("Captain" to "Vice Captain")
        LazyColumn(modifier = Modifier.fillMaxSize().border(2.dp, Color.Green)) {
            itemsIndexed(names) { index, item ->

                Column(
                    modifier = Modifier
                        .padding(top = 24.dp)
                        .fillMaxWidth()
                        .drawWithContent {

                            translate(
                                left= 120.dp.toPx(), top = 0f
                            ){
                                drawLine(
                                    color = Color.Black,
                                    start = Offset(0f,0f),
                                    end = Offset(0f, size.height),
                                    strokeWidth = 2.dp.toPx(),
                                )

                                translate(
                                    left= 10.dp.toPx(), top = 0f
                                ){
                                    this@drawWithContent.drawContent()
                                }

                            }
                        }


                ) {
                    Text(text = item.first, color = Color.Red)
                    Text(text = item.second, color = Color.Blue)
                }
            }
        }
    }
}
Thracian
  • 43,021
  • 16
  • 133
  • 222
  • 1
    This is the easiest way to align content based on what you draw. Since you can set position of content based on where your drawings are. Maybe not an issue for this question but as the things get more complex being able to change position, scale or rotation of content with such an ease is amazing. One of the reasons i like drawing with compose – Thracian May 03 '23 at 21:51
  • Thanks @Thracian for teaching me. I am not great in maths. So that's why I made mistake all of this. – Kotlin Learner May 03 '23 at 21:55