CodingProfile
CodingProfile

Reputation: 189

Every element from loop should fill all the free space that is available in the Row

I have elements that I loop through and clicked element changes background to green. I want every element to fill all the free space that is available in the Row. But if I provide weight(1f) it shows only one element that takes all the space, but there should be three elements or whatever count of elements I have passed from outside.

enter image description here

@Composable
fun BottomMenu(
    items: List<BottomMenuContent>,
    modifier: Modifier = Modifier,
    activeHighlightColor: Color = Green,
    activeTextColor: Color = Color.White,
    inactiveTextColor: Color = Color.Black,
    initialSelectedItemIndex: Int = 0
) {
    var selectedItemIndex by remember {
        mutableStateOf(initialSelectedItemIndex)
    }
    Row(
        verticalAlignment = Alignment.CenterVertically,
        modifier = modifier
            .fillMaxWidth()
            .background(Gray)
            .padding(4.dp)


    ) {
            items.forEachIndexed { index, item ->
                BottomMenuItem(
                    item = item,
                    isSelected = index == selectedItemIndex,
                    activeHighlightColor = activeHighlightColor,
                    activeTextColor = activeTextColor,
                    inactiveTextColor = inactiveTextColor
                ) {
                    selectedItemIndex = index
                }
        }

        }
    }

@Composable
fun BottomMenuItem(
    modifier: Modifier = Modifier,
    item: BottomMenuContent,
    isSelected: Boolean = false,
    activeHighlightColor: Color = Green,
    activeTextColor: Color = Color.White,
    inactiveTextColor: Color = Color.Black,
    onItemClick: () -> Unit
) {
Row( ) {
        Box(
            contentAlignment = Alignment.Center,
            modifier = Modifier
                .clickable {
                    onItemClick()
                }
                .background(if (isSelected) activeHighlightColor else Color.Transparent)
                .weight(1f)
                .padding(top = 14.dp, bottom = 14.dp,)
  
        ) {
            Text(
                text = item.title,
                color = if(isSelected) activeTextColor else inactiveTextColor
            )
        }


}}

Upvotes: 5

Views: 266

Answers (1)

z.g.y
z.g.y

Reputation: 6287

Remove the weight from the box and instead put it in its parent Row, I modified your code and please look where the weight is placed.

Your BottomMenu

@Composable
fun BottomMenu() {
    Row(
        verticalAlignment = Alignment.CenterVertically,
        modifier = Modifier
            .background(Color.LightGray)
            .fillMaxWidth()
    ) {

        (0..7).forEach {
            BottomMenuItem()
        }
    }

}

Your BottomMenuItem

@Composable
fun RowScope.BottomMenuItem() {
    Row(
        modifier = Modifier.weight(1f) // remove the weight from the box inside and put it over here instead
    ) {
        Box(
            modifier = Modifier
                .background(Color.Green) 
                // remove the weigth(1f) from here
        ) {
            Text(
                modifier = Modifier.fillMaxWidth(),
                text = "Test",
                color = Color.DarkGray
            )
        }
    }
}

Your BottomMenuItem is an extension of a RowScope, so its top level composable can be configured with Row properties such as weight

Output of the code above.

enter image description here

Upvotes: 1

Related Questions