Duncan Hill
Duncan Hill

Reputation: 547

Kotlin Compose, Vertical Center Image & Bottom align text

I'm currently transitioning from SwiftUI to Kotlin Compose and struggling with something that should be easy but I maybe tackling in the wrong way.

What I'm trying to do is have an image that is centrally aligned both vertically & horizontally, basically in the centre of the screen. Then I need two text values at the bottom of the screen. How should I tackle this, my current approach is to have a column set to .fillmaxsize() within this I have two rows one with an image, the other with another column with two rows of text and a Spacer(modifier = Modifier.weight(1f)) between the two rows

Everything is correctly horizontally aligned and the two text fields correctly bottom aligned, its the image that I'm unable to vertically centre.

@Composable
fun testScreen() {

    Column(Modifier
        .background(Color.Blue)
        .fillMaxSize(),
        verticalArrangement = Arrangement.Center
       ) {
        Row(Modifier
            .fillMaxWidth()
            .background(Color.Green),
            horizontalArrangement = Arrangement.Center,
            verticalAlignment = Alignment.CenterVertically

        ) {
            Image(
                painterResource(R.someimagefile),
                contentDescription = "",
                contentScale = ContentScale.Crop,
                modifier = Modifier
                    .size(300.dp)
            )
        }

        Spacer(modifier = Modifier.weight(1f))

        Row(Modifier
                .background(Color.Red)
                .fillMaxWidth(),
                horizontalArrangement = Arrangement.Center,
        ) {
            Column() {
                Text(
                    text = "Text 1",
                    color = Color.Black,
                    textAlign = TextAlign.Center,
                    modifier = Modifier
                        .align(Alignment.CenterHorizontally)

                )
                Text(
                    text = "Text 2",
                    fontSize = 20.sp,
                    color = Color.Black,
                    textAlign = TextAlign.Center,
                    modifier = Modifier
                        .align(Alignment.CenterHorizontally)
                )
            }
        }
    }
}

Upvotes: 0

Views: 2183

Answers (1)

Raghunandan
Raghunandan

Reputation: 133570

If i understand your question correctly you want to center a image and have two texts on different line at the bottom.

You could use a constraint layout and you can center the image top to parent, start to parent, end to parent and bottom to parent. create a column/row and add constraints start to parent end to parent and bottom to parent. https://developer.android.com/jetpack/compose/layouts/constraintlayout

    ConstraintLayout(modifier = Modifier.fillMaxSize()) {
        val (image, columnTexts) = createRefs()

        Image(
            painter = painterResource(R.drawable.ic_launcher_background),
            contentDescription = "",
            contentScale = ContentScale.Crop,
            modifier = Modifier
                .size(300.dp)
                .clickable {  }
                .constrainAs(image) {
                top.linkTo(parent.top)
                start.linkTo(parent.start)
                end.linkTo(parent.end)
                bottom.linkTo(parent.bottom)
            }
        )


        Column(modifier= Modifier.wrapContentHeight().constrainAs(columnTexts) {
            end.linkTo(parent.end)
            start.linkTo(parent.start)
            bottom.linkTo(parent.bottom, margin = 16.dp,)
        }) {
            Text("Text1", modifier = Modifier.wrapContentWidth())
            Text("Text2", modifier = Modifier.wrapContentWidth())

        }
}

enter image description here

Alternative way using box results in the same ui

@Composable
fun AlternateUI() {
    Box(
        modifier = Modifier.fillMaxSize()
    ) {
        Column(
            modifier = Modifier.align(Alignment.Center),
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            Image(
                painter = painterResource(R.drawable.ic_launcher_background),
                contentDescription = "",
                contentScale = ContentScale.Crop,
                modifier = Modifier
                    .size(300.dp)
                    .clickable { })
        }
        BottomText(
            modifier = Modifier
                .padding(bottom = 10.dp)
                .align(Alignment.BottomCenter)
        )
    }
}

@Composable
fun BottomText(modifier: Modifier) {
    Column(
        modifier = modifier.wrapContentWidth().wrapContentHeight().padding(10.dp),
    ) {
        Text(text = "line1", textAlign = TextAlign.Center)
        Text(text = "line2", textAlign = TextAlign.Center)
    }
}

Upvotes: 1

Related Questions