kotlininterfaceandroid-jetpack-compose

How to align buttons and text in Jetpack Compose


I am unable to align buttons and text in Jetpack Compose. I'm trying to make the text (item names) left aligned and the buttons as a column as shown on the bottom screen. At the moment it looks as shown on the top screen. Sorry, I'm not very experienced, but I've really tried a lot of options and I'm doing something wrong.

My code:

Column(
        Modifier
            .fillMaxSize()
            .background(EditBackground)
            .padding(vertical = 8.dp, horizontal = 8.dp),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Text(
            modifier = Modifier
                .align(Alignment.CenterHorizontally),
            text = nation.nationName,
            style = Typography.titleLarge,
            fontSize = 17.sp,
            color = colorScheme.onPrimary,
            maxLines = 1,
            overflow = TextOverflow.Ellipsis
        )
        
        EditTextField(
            label = "nationName",
            value = nation.nationName,
            onValueChange = { nation = nation.copy(nationName = it) }
        )
        EditTextField(
            label = "nationalityName",
            value = nation.nationalityName,
            onValueChange = { nation = nation.copy(nationalityName = it) }
        )
        EditTextField(
            label = "nationAbbrv",
            value = nation.nationAbbrv,
            onValueChange = { nation = nation.copy(nationAbbrv = it) }
        )

        Row(
            modifier = Modifier
                .fillMaxWidth()
                .padding(top = 4.dp),
        ) {
            Text(text = "continentId", color = Color.White)
            Spacer(modifier = Modifier.weight(0.05f))
            RemoveAddText(
                inputValue = nation.continentId,
                onValueChange = {
                    nation = nation.copy(continentId = it)
                }
            )
            Spacer(modifier = Modifier.weight(0.1f))
            Text(text = "capitalCityId", color = Color.White)
            Spacer(modifier = Modifier.weight(0.05f))
            RemoveAddText(
                inputValue = nation.capitalCityId,
                limit = 125000,
                addval = 1000,
                onValueChange = {
                    nation = nation.copy(capitalCityId = it)
                }
            )
            Spacer(modifier = Modifier.weight(0.1f))
            Text(text = "nationalStadiumId", color = Color.White)
            Spacer(modifier = Modifier.weight(0.05f))
            RemoveAddText(
                inputValue = nation.nationalStadiumId,
                limit = 125000,
                addval = 1000,
                onValueChange = {
                    nation = nation.copy(nationalStadiumId = it)
                }
            )
        }
        
        Row(
            modifier = Modifier
                .fillMaxWidth()
                .padding(top = 4.dp),
        ) {
            Text(text = "stateOfDevelopment", color = Color.White)
            Spacer(modifier = Modifier.weight(0.05f))
            RemoveAddText(
                inputValue = nation.stateOfDevelopment,
                onValueChange = {
                    nation = nation.copy(stateOfDevelopment = it)
                }
            )
            Spacer(modifier = Modifier.weight(0.1f))
            Text(text = "groupMembership", color = Color.White)
            Spacer(modifier = Modifier.weight(0.05f))
            RemoveAddText(
                inputValue = nation.groupMembership,
                limit = 125000,
                addval = 1000,
                onValueChange = {
                    nation = nation.copy(groupMembership = it)
                }
            )
            Spacer(modifier = Modifier.weight(0.1f))
            Text(text = "gameImportance", color = Color.White)
            Spacer(modifier = Modifier.weight(0.05f))
            RemoveAddText(
                inputValue = nation.gameImportance,
                limit = 125000,
                addval = 1000,
                onValueChange = {
                    nation = nation.copy(gameImportance = it)
                }
            )
        }
        
        Row(
            modifier = Modifier
                .fillMaxWidth()
                .padding(top = 4.dp),
        ) {
            Text(text = "seasonUpdateDay", color = Color.White)
            Spacer(modifier = Modifier.weight(0.05f))
            RemoveAddText(
                inputValue = nation.seasonUpdateDay,
                onValueChange = {
                    nation = nation.copy(seasonUpdateDay = it)
                }
            )
            Spacer(modifier = Modifier.weight(0.1f))
            Text(text = "rivalId", color = Color.White)
            Spacer(modifier = Modifier.weight(0.05f))
            RemoveAddText(
                inputValue = nation.rivalId,
                limit = 125000,
                addval = 1000,
                onValueChange = {
                    nation = nation.copy(rivalId = it)
                }
            )
            Spacer(modifier = Modifier.weight(0.1f))
            Text(text = "selected", color = Color.White)
            Spacer(modifier = Modifier.weight(0.05f))
            RemoveAddText(
                inputValue = nation.selected,
                limit = 125000,
                addval = 1000,
                onValueChange = {
                    nation = nation.copy(selected = it)
                }
            )
        }
        
        Row(
            modifier = Modifier
                .fillMaxWidth()
                .padding(top = 4.dp),
        ) {
            Text(text = "regionId", color = Color.White)
            Spacer(modifier = Modifier.weight(0.05f))
            RemoveAddText(
                inputValue = nation.regionId,
                onValueChange = {
                    nation = nation.copy(regionId = it)
                }
            )
            Spacer(modifier = Modifier.weight(0.1f))
            Text(text = "isRanked", color = Color.White)
            Spacer(modifier = Modifier.weight(0.05f))
            RemoveAddText(
                inputValue = nation.isRanked,
                limit = 125000,
                addval = 1000,
                onValueChange = {
                    nation = nation.copy(isRanked = it)
                }
            )
            Spacer(modifier = Modifier.weight(0.1f))
            Text(text = "fifaRanking", color = Color.White)
            Spacer(modifier = Modifier.weight(0.05f))
            RemoveAddText(
                inputValue = nation.fifaRanking,
                limit = 125000,
                addval = 1000,
                onValueChange = {
                    nation = nation.copy(fifaRanking = it)
                }
            )
        }

And:

@Composable
fun EditTextField(
    label: String,
    value: String,
    onValueChange: (String) -> Unit
) {
    Row(
        Modifier
            .fillMaxWidth()
            .padding(top = 4.dp)
    ) {
        Text(text = label, color = Color.White)
        Spacer(modifier = Modifier.width(8.dp))
        BasicTextField(
            modifier = Modifier
                .width(360.dp)
                .height(24.dp)
                .background(
                    EditTextFieldBackground,
                    shapes.extraSmall
                ),
            value = value,
            onValueChange = onValueChange,
            textStyle = LocalTextStyle.current.copy(
                color = EditTextFieldTextColor,
                textAlign = TextAlign.Center
            ),
            keyboardOptions = KeyboardOptions(
                keyboardType = KeyboardType.Text,
                imeAction = ImeAction.Done
            )
        )
    }
}

@Composable
fun RemoveAddText(
    modifier: Modifier = Modifier,
    inputValue: Int,
    onValueChange: (value: Int) -> Unit = {},
    isNegativeAllowed: Boolean = false,
    addval: Int = 1,
    limit: Int? = null
) {
    var value by remember { mutableIntStateOf(inputValue) }
    val coroutine = rememberCoroutineScope()
    var isLongPress by remember { mutableStateOf(false) }

    Row(
        modifier = modifier
            .height(24.dp)
            .background(
                EditTextFieldBackground,
                shapes.extraSmall
            )
            .width(130.dp),
        horizontalArrangement = Arrangement.SpaceBetween
    ) {
        IconButton(onClick = {
            value--
            onValueChange(value)
        }) {
            Icon(
                imageVector = ImageVector.vectorResource(id = R.drawable.remove_icon),
                contentDescription = "",
                tint = Color.White,
                modifier = Modifier
                    .size(16.dp)
                ////code +-
            )
        }
        Text(
            text = value.toStringWithEmpty(),
            color = EditTextFieldTextColor,
            textAlign = TextAlign.Center
        )
        IconButton(onClick = {
            value++
            onValueChange(value)
        }) {
            Icon(
                imageVector = ImageVector.vectorResource(id = R.drawable.add_icon),
                contentDescription = "",
                tint = Color.White,
                modifier = Modifier
                    .size(16.dp)
                    ////code ++
            )
        }
    }
}

Please see screenshot

The screenshot above is what I have now. I want the alignment to be as shown in the bottom screenshot.


Solution

  • Such grid-like layout can be achieved with nested Rows and Columns:

    // Grid
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .padding(top = 4.dp),
    ) {
        // The 1st column
        Column(
            modifier = Modifier.weight(1f)
        ) {
            Row {
                Text(text = "continentId", color = Color.White)
                Spacer(modifier = Modifier.weight(1f))
                RemoveAddText()
            }
            Row {
                Text(text = "stateOfDevelopment", color = Color.White)
                Spacer(modifier = Modifier.weight(1f))
                RemoveAddText()
            }
            Row {
                Text(text = "seasonUpdateDay", color = Color.White)
                Spacer(modifier = Modifier.weight(1f))
                RemoveAddText()
            }
            Row {
                Text(text = "regionId", color = Color.White)
                Spacer(modifier = Modifier.weight(1f))
                RemoveAddText()
            }
        }
        // The 2nd column
        Column(
            modifier = Modifier.weight(1f)
        ) {
        //....
    }
    

    screenshot