androidandroid-jetpack-composeandroid-jetpackandroid-layout-weightandroid-jetpack-compose-layout

Unable to specify weight in Composable with no Column declared in it


I am trying to build a simple calculator using jetpack compose, my composables are:

When I apply a Modifier.weight to each Row it doesnt compile because the Column is declared in a different Composable function.

How can I solve this issue?

@Composable
fun calculatorRow(weight: Float, symbols: List<String>, operate: (String) -> Unit) {
    Row(
        horizontalArrangement = Arrangement.Center,
        Modifier.weight(weight)
    ) {
        symbols.map { symbol ->
            Button(
                modifier = Modifier
                    .weight(1f)
                    .padding(1.dp)
                    .clip(RoundedCornerShape(8.dp)),
                onClick = {
                    operate(symbol)
                }
            ) {
                Text(text = symbol)
            }
        }
    }
}

@Composable
fun calculator(padding: PaddingValues) {
    var operations = remember {
        mutableStateOf("")
    }
    val operate =
        { word: String -> if (word == "C") operations.value = "" else operations.value += word }
    Column(
        Modifier
            .padding(padding)
    ) {
        Card {
            Text(
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(5.dp),
                text = operations.value
            )
        }
        calculatorRow(1f, listOf("1", "2", "3", "+"), operate)
        calculatorRow(1f, listOf("4", "5", "6", "-"), operate)
        calculatorRow(1f, listOf("7", "8", "9", "*"), operate)
        calculatorRow(1f, listOf("0", ".", "C", "/"), operate)

    }
}


@Preview
@Composable
fun preview() {
    calculator(PaddingValues(10.dp))
}

Solution

  • that's the expected behaviour because calculatorRow Composeable could be called from any other composable function even the funs that u can't use weight in the(exp:Box) so instead you can pass a modifier to calculatorRow and use it to pass the weight from the right place (the columnScope) in order for it to be compiled.

    @Composable
    fun calculator(padding: PaddingValues) {
        var operations = remember {
            mutableStateOf("")
        }
        val operate =
            { word: String -> if (word == "C") operations.value = "" else 
        operations.value += word }
            Column(
            Modifier
                .padding(padding)
        ) {
            Card {
                Text(
                    modifier = Modifier
                        .fillMaxWidth()
                        .padding(5.dp),
                    text = operations.value
                )
            }
            calculatorRow(
                symbols = listOf("1", "2", "3", "+"),
               operate = operate,
               modifier = Modifier
                    .weight(1f)
            )
            calculatorRow(
                symbols = listOf("4", "5", "6", "-"),
                operate = operate,
               modifier = Modifier
                    .weight(1f)
            )
            calculatorRow(
                symbols = listOf("7", "8", "9", "*"),
                operate = operate,
                modifier = Modifier
                    .weight(1f)
            )
           calculatorRow(
                symbols = listOf("0", ".", "C", "/"),
                operate = operate,
                modifier = Modifier
                    .weight(1f)
            )
    
        }
    }
    
    
    
    
    @Composable
    fun calculatorRow(
        modifier: Modifier,
        symbols: List<String>,
        operate: (String) -> Unit,
    ) {
        Row(
            horizontalArrangement = Arrangement.Center,
            modifier = modifier
        ) {
            symbols.map { symbol ->
                Button(
                    modifier = Modifier
                        .weight(1f)
                        .padding(1.dp),
                    onClick = {
                        operate(symbol)
                    }
                ) {
                    Text(text = symbol)
                }
            }
        }
    }