Ambran
Ambran

Reputation: 2627

Column weight distribution in Compose

I have a Column component (SettingsGraphicSelectComposeView.kt) which needs to have a weight of 1f (modifier.weight(weight = 1f)) so that multiple of this component in a container, would be distributed evenly. Problem is that when upgrading Compose from alpha02 to alpha06, assigning the above modifier to a Column is no longer a possibility.

Here is the components code:

@Composable
fun SettingsGraphicSelectComposeView(
    modifier: Modifier = Modifier,
    textStyles: TextStyles = KoinJavaComponent.inject(TextStyles::class.java).value,
    viewModel: ItemViewModel.GraphicSelect
) {
    Column(
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center
        modifier = modifier.weight(weight = 1f) // <-- in alpha06 this gives an error
    ) {
        Image(
            asset = vectorResource(id = viewModel.imageId)
        )
        Text(
            modifier = modifier
                .padding(
                    start = dimensionResource(id = R.dimen.spacingL),
                    top = dimensionResource(id = R.dimen.spacingL),
                    end = dimensionResource(id = R.dimen.spacingL),
                    bottom = dimensionResource(id = R.dimen.spacingS)
                ),
            text = viewModel.caption,
            style = textStyles.TitleSmall.merge(TextStyle(color = colorResource(id = R.color.tint_secondary)))
        )
        RadioButton(
            selected = viewModel.selected,
            onClick = viewModel.action,
            colors = RadioButtonConstants.defaultColors(
                selectedColor = colorResource(R.color.brand),
                unselectedColor = colorResource(R.color.tint_secondary)
            )
        )
    }
}

This component is placed in the following compose view:

Surface(color = colorResource(id = R.color.background)) {
        Column(
            modifier = Modifier
                .fillMaxHeight()
        ) {
            items.value?.let { items ->
                val switchers = items.filter { it.viewModel is ItemViewModel.Switcher }
                val graphicSelects = items.filter { it.viewModel is ItemViewModel.GraphicSelect }

                if (switchers.isNotEmpty()) {
                    val autoSwitcher = switchers[0]
                    SettingsSwitcherComposeView(viewModel = autoSwitcher.viewModel as ItemViewModel.Switcher)
                }
                Row(
                    modifier = Modifier
                        .padding(horizontal = dimensionResource(id = R.dimen.spacing2XL))
                ) {
                    if (graphicSelects.size > 1) {
                        val lightSelector = graphicSelects[0]
                        val darkSelector = graphicSelects[1]

                        Row(
                            modifier = Modifier
                                .border(
                                    width = 1.dp,
                                    color = colorResource(R.color.highlight),
                                    shape = RoundedCornerShape(
                                        dimensionResource(R.dimen.content_corner_radius)
                                    )
                                )
                                .padding(vertical = dimensionResource(id = R.dimen.spacing2XL))
                        ) {
                            Row {
                                SettingsGraphicSelectComposeView(
                                    viewModel = lightSelector.viewModel as ItemViewModel.GraphicSelect
                                ) // <-- This should have the weight 1f
                                Spacer(
                                    modifier = Modifier
                                        .preferredWidth(1.dp)
                                        .preferredHeight(160.dp)
                                        .background(color = colorResource(R.color.highlight))
                                )
                                SettingsGraphicSelectComposeView(
                                    viewModel = darkSelector.viewModel as ItemViewModel.GraphicSelect
                                ) // <-- This should have the weight 1f
                            }
                        }
                    }
                }
            }
        }
    }

Should look like this:

enter image description here

But without the weight it looks like this:

enter image description here

Upvotes: 3

Views: 9125

Answers (3)

Maddy Sharma
Maddy Sharma

Reputation: 4956

Here is the solution : Modifier --> "Arrangement.SpaceEvenly"

Row(
        modifier = Modifier.fillMaxWidth(),
        verticalAlignment = Alignment.CenterVertically,
        horizontalArrangement = Arrangement.SpaceEvenly,
    )

If you wants to give bigger space to any specific Row item, you can handle it dynamically by using your own condition :

For eg :

modifier=Modifier.then(Modifier.weight(if(myItem == index) 2f else 1f))

                                **'OR'**

modifier=Modifier.then(Modifier.weight(if(myItem .title=="GOLF") 1.5f else 1f))

Upvotes: 1

Ambran
Ambran

Reputation: 2627

It seems like the weight modifier can only attributed to Column if this column is a child of a Row, so a team member suggested replacing the Row elements containing the SettingsGraphicSelectComposeView with Column and it made the weight attribute "legal" if you will, because we're in a RowScope, and that works.

enter image description here

Not sure what to think about that but it works and as Compose is still at alpha07 right now (new version since I made the post), things might change again in the future.

Here is the change:

Row(
    modifier = modifier
        .padding(horizontal = dimensionResource(id = R.dimen.spacing2XL))
        .border(
            width = 1.dp,
            color = colorResource(R.color.highlight),
            shape = RoundedCornerShape(
                dimensionResource(R.dimen.content_corner_radius)
            )
        )
        .fillMaxWidth()
) {
    Column(modifier = Modifier.weight(weight = 1f).padding(vertical = dimensionResource(id = R.dimen.spacing2XL))) {
        SettingsGraphicSelectComposeView(
            modifier = Modifier.align(Alignment.CenterHorizontally),
            viewModel = viewModel.light.viewModel as ItemViewModel.GraphicSelect
        )
    }

    Spacer(
        modifier = Modifier
            .padding(top = dimensionResource(id = R.dimen.spacing2XL))
            .preferredWidth(1.dp)
            .preferredHeight(160.dp) // TODO: Find a way to make this max AUTO height, not fixed
            .background(color = colorResource(R.color.highlight))
    )

    Column(modifier = Modifier.weight(weight = 1f).padding(vertical = dimensionResource(id = R.dimen.spacing2XL))) {
        SettingsGraphicSelectComposeView(
            modifier = Modifier.align(Alignment.CenterHorizontally),
            viewModel = viewModel.dark.viewModel as ItemViewModel.GraphicSelect
        )
    }
}

Upvotes: 3

Saurabh Thorat
Saurabh Thorat

Reputation: 20684

Try using Modifier.weight(1f) in your Row itself, so it takes Modifier.weight() from RowScope:

Row {
    SettingsGraphicSelectComposeView(
        modifier = Modifier.weight(1f),
        viewModel = lightSelector.viewModel as ItemViewModel.GraphicSelect
    )
    Spacer(
        modifier = Modifier
            .preferredWidth(1.dp)
            .preferredHeight(160.dp)
            .background(color = colorResource(R.color.highlight))
    )
    SettingsGraphicSelectComposeView(
        modifier = Modifier.weight(1f),
        viewModel = darkSelector.viewModel as ItemViewModel.GraphicSelect
    )
}

Upvotes: 2

Related Questions