android-jetpack-compose

How to draw over ".weight" Element?


My Composeable is nearly to my liking, the last part would be to add an Icon on the top right of the Screen.
Here comes the issue, I'm using .weight(0.5f) two times to ensure, that my data has an automated maximum length and is visually shown with the same width regardless of how long the Text is.
I also need the Text to be aware of the Icon, so that the Text does not overflow (write over) the Icon or disappear behind the icon.

How can I achieve my goal?

My Composeable Code:

Row(
        modifier = Modifier
            .fillMaxWidth()
            .height(IntrinsicSize.Max)
    ) 
{
    Column{
       // Other Stuff without ".weight" Modifier
    }
    Column(verticalArrangement = Arrangement.SpaceAround) 
    {
        Row {
            Row(
                modifier = Modifier.weight(0.5f)
            ) {
                Icon(
                    imageVector = Icons.Outlined.Person,
                    contentDescription = "desc"
                )
                Text(
                    text = "text 1",
                    maxLines = 1,
                    overflow = TextOverflow.Ellipsis
                )
            }
            if (CustomConditionIsTrue) {
                Row(
                    modifier = Modifier.weight(0.5f)
                ) {
                    Icon(
                        imageVector = Icons.Outlined.Home,
                        contentDescription = "desc"
                    )
                    Text(
                        text = "text 2",
                        maxLines = 1,
                        overflow = TextOverflow.Ellipsis
                    )
                }
            }
        }
    }
    // Important Icon which need to be visible and accessible
    Column(
            modifier = Modifier.weight(0.2f),
            verticalArrangement = Arrangement.Top,
            horizontalAlignment = Alignment.End
        ) {
        Icon(
                imageVector = Icons.Outlined.Info,
                contentDescription = "important desc"
        )
    }
}

Due to using .weight(0.5f), my Icons.Outlined.Info is not displayed (not visible) anymore.
After removing .weight(0.5f), my Icons.Outlined.Infois visible, but my text is poorly formatted.

I googled about drawing an composeable in the top right corner and found Box as solution, which unfortunately does not "ignore" the .weight Modifier and the result is the same (Icon not visible).

I've set the zIndex Value to 1.0E9f and expected the Icon to be drawn regardless of the .weight Modifier, but that also didn't work (Icon is not visible). It might also cause text overflow if it did if I think about that...


Solution

  • Please try out the following adjustments.

    First, add the weight Modifier to the Column that holds the nested Rows:

    Column(
        modifier = Modifier.weight(1f),
        verticalArrangement = Arrangement.SpaceAround
    ) {
        Row {
            // the two nested Rows
        }
    }
    

    As a result, the two unweighted sibling Columns will be measured first. Then, all remaining space in the top-level Row will be given to the middle Column. This ensures that all three Columns are visible.

    Then, remove the weight Modifier from the info Icon:

    // Important Icon which need to be visible and accessible
    Column(
        verticalArrangement = Arrangement.Top,
        horizontalAlignment = Alignment.End
    ) {
        Icon(
            imageVector = Icons.Outlined.Info,
            contentDescription = "important desc"
        )
    }
    

    As a result, this Column will only take up as much space in the top-level Row as it actually needs.

    Output:

    enter image description here


    As a side note, you can probably remove the middle Column and still get the same results:

    Row(
        modifier = Modifier
            .fillMaxWidth()
            .height(IntrinsicSize.Max)
    ) {
        Column{
            // Other Stuff without ".weight" Modifier
        }
       
        Row(
            modifier = Modifier.weight(1f),
            verticalAlignment = Alignment.CenterVertically
        ) {
            Row(
                modifier = Modifier.weight(0.5f)
            ) {
                //...
            }
            if (true) {
                Row(
                    modifier = Modifier.weight(0.5f)
                ) {
                    //...
                }
            }
        }
        // Important Icon which need to be visible and accessible
        Column(
            verticalArrangement = Arrangement.Top,
            horizontalAlignment = Alignment.End
        ) {
            Icon(
                imageVector = Icons.Outlined.Info,
                contentDescription = "important desc"
            )
        }
    }