androidkotlinandroid-jetpack-composeandroid-jetpack-compose-layouthorizontal-alignment

What is the working logic of Row Arrangement in Android jetpack compose?


I've been currently developing and learning android jetpack compose and there are some things I don't know and wonder about this. One thing I'm wondering I'm trying to do a back button positioned in the upper left corner of the screen and a text positioned in the middle. I originally wrote this code like this:

Row(modifier = Modifier
        .padding(5.dp)
        .fillMaxWidth()) {
        Image(
            modifier = Modifier
                .clickable {
                    onBackClick()
                }
                .padding(4.dp),
            alignment = Alignment.CenterStart,
            painter = painterResource(id = R.drawable.ic_back),
            contentDescription = "back")
        
        Row(
            horizontalArrangement = Arrangement.Center){
            Text(text = "Help")
        }
    }

Since I gave a modifier.FillMaxWidth in the first Row, I didn't give it in the second because it has a child component, I thought it was unnecessary, and I gave a horizontalArrangment center in the second Row to align the Text in the middle, but even though I did this, the back button and the text appeared side by side on the upper left.

However, when I rewrote my code like this, when I added the second Row modifier.FillMaxWidth, it worked fine.

Row(modifier = Modifier
        .padding(5.dp)
        .fillMaxWidth()) {
        Image(
            modifier = Modifier
                .clickable {
                    onBackClick()
                }
                .padding(4.dp),
            alignment = Alignment.CenterStart,
            painter = painterResource(id = R.drawable.ic_back),
            contentDescription = "back")
        
        Row(modifier = Modifier.fillMaxWidth(), // <----
            horizontalArrangement = Arrangement.Center){
            Text(text = "Yardım")
        }
    }

I added this modifier = Modifier.fillMaxWidth() second Row component

Why is it necessary to give Modifier.fillMaxWidth() on the second Row? We already give it in the parent component? what's going on in the background?


Solution

  • The horizontalArrangement in the Row = the horizontal arrangement of the layout's children in the available space.

    Using:

       Row(modifier = Modifier
              .fillMaxWidth()
              .background(Yellow),
            horizontalArrangement = Arrangement.Center
       ) {
            Text(text = "Yardım")
       }
    

    enter image description here

    Using:

       Row(modifier = Modifier
              //.fillMaxWidth()
              .background(Yellow),
            horizontalArrangement = Arrangement.Center
       ) {
            Text(text = "Yardım")
       }
    

    enter image description here

    In any case using this layout the Text(text = "Yardım") is not centered in the whole 1st Row but only in the space occupied by the 2nd Row.

    If you want to center the text in the whole 1st Row you can use a Box as parent container.
    In this case use the align modifier in the children to a specific Alignment within the Box. This alignment will have priority over the Box's alignment parameter.

    Something like:

        Box(
            modifier = Modifier
                .padding(5.dp)
                .fillMaxWidth(),
            contentAlignment = Alignment.Center,
        ) {
    
            Row(modifier = Modifier
                .fillMaxWidth()
                .align(Alignment.Center)
                .background(Yellow), 
                horizontalArrangement = Arrangement.Center
            ){
                Text(text = "Yardım")
            }
    
            Image(
                modifier = Modifier
                    .align(Alignment.CenterStart),
                //.....
            )
            
        }
    

    enter image description here