androidkotlinandroid-jetpack-composeandroid-jetpackjetpack

Align two boxes vertically in a column


I am trying to design a UI like this in Jetpack Compose:

enter image description here

Whenever an option is selected, it should get underlined in the UI as shown above. However, when I try to arrange it in Jetpack compose I get a very weird behavior:

enter image description here

Here's what I tried:


@Composable
fun PaymentsScreen(navController: NavController) {
    var textState by remember { mutableStateOf("EA DUMPLING CARDS") }

    TitleOptionBar(
        options = listOf("EA DUMPLING CARDS", "OTHER PAYMENTS"),
        selectedOption = textState,
        onOptionSelected = {newOption -> textState = newOption}
    )


}

@Composable
fun TitleOptionBar(
    options: List<String>,
    selectedOption: String,
    onOptionSelected: (String) -> Unit
) {
    Row(
        modifier = Modifier.fillMaxWidth(),
        horizontalArrangement = Arrangement.SpaceEvenly
    ) {
        options.forEach { option ->
            // Create individual option views here
            Box(
                modifier = Modifier.weight(weight = 1F).clickable { onOptionSelected(option) },
                contentAlignment = Alignment.Center
            ) {
                Text(
                    text = option,
                    modifier = Modifier.padding(16.dp),
                    fontWeight = if (option == selectedOption) FontWeight.Bold else FontWeight.Light
                )
                }

            if (option == selectedOption) {
                Box(
                    modifier = Modifier
                        .height(5.dp)
                        .background(Color.Blue)
                        .weight(weight = 1F)
                ) {
                    // This line will appear under the selected box
                }
            }

        }

        }
    }

What should I change in the code?


Solution

  • You can try something like this:

    Row(
        modifier = Modifier
            .fillMaxWidth()
            .horizontalScroll(rememberScrollState()),
        horizontalArrangement = Arrangement.SpaceEvenly
    ) {
        options.forEach { option ->
            // Create individual option views here
            Box(
                modifier = Modifier
                    .height(40.dp)
                    .padding(horizontal = 16.dp)
                    .width(IntrinsicSize.Max)
                    .clickable {
                        onOptionSelected(option)
                    }
            ) {
                Text(
                    modifier = Modifier
                        .align(Alignment.Center)
                        .fillMaxWidth(),
                    text = option,
                    fontWeight = if (option == selectedOption) FontWeight.Bold else FontWeight.Light
                )
                androidx.compose.animation.AnimatedVisibility(
                    visible = option == selectedOption,
                    modifier = Modifier
                        .align(Alignment.BottomCenter)
                ) {
                    Surface(
                        modifier = Modifier
                            .height(3.dp)
                            .fillMaxWidth(),
                        shape = RoundedCornerShape(3.dp),
                        color = Color.Blue
                    ) {}
                }
            }
    
    
        }
    
    }
    

    Also, you can checkout material tab.