'ConstraintLayout in jetpack compose giving strange results

I'm trying to do a ConstraintLayout in jetpack compose as I am having problems doing too many nested Columns and Rows.

Here is what I have:

@Composable
fun StateAndZipLayout(
    modifier: Modifier,
    onFormChanged: (FormType, String) -> Unit,
    selectedLocation: Address,
    stateError: Boolean,
    zipError: Boolean
) {
val configuration = LocalConfiguration.current

val screenWidth = configuration.screenWidthDp.dp
val componentWidth = (screenWidth - 48.dp)/2

ConstraintLayout(modifier = Modifier
    .fillMaxWidth()
    .wrapContentHeight())  {
    val rightGuideline = createGuidelineFromStart(0.5f)
    val (stateDropDown, shippingField) = createRefs()
    StateSelection(
        modifier = modifier
            .constrainAs(stateDropDown) {
                top.linkTo(parent.top)
                bottom.linkTo(parent.bottom)
                end.linkTo(rightGuideline, margin = 8.dp)
            }
            .requiredWidth(componentWidth)
            .wrapContentHeight(),
        onFormChanged = onFormChanged,
        selectedLocation = selectedLocation,
        label = "State",
        error = stateError,
    )
    ShippingField(
        modifier = modifier
            .constrainAs(shippingField) {
                start.linkTo(rightGuideline, margin = 8.dp)
                top.linkTo(stateDropDown.top)
                bottom.linkTo(stateDropDown.bottom)
                end.linkTo(parent.end)
            }
            .requiredWidth(componentWidth),
        onFormChanged = onFormChanged,
        formType = FormType.SHIPPING_ZIP,
        label = "Zip",
        valueField = selectedLocation.zipCode,
        error = zipError
    )
    }
}

Here is my state selection view:

@Composable
fun StateSelection(
    modifier: Modifier,
    onFormChanged: (FormType, String) -> Unit,
    selectedLocation: Address,
    error: Boolean,
    label: String
) {
// State variables
val statesMap = AddressUtils.mapOfAmericanStatesToValue
var stateName: String by remember { mutableStateOf(selectedLocation.shippingState) }
var expanded by remember { mutableStateOf(false) }
val focusManager = LocalFocusManager.current
var errorState by remember { mutableStateOf(error) }
Column {


    Row(
        Modifier
            .clickable {
                expanded = !expanded
            },
    ) { // Anchor view
        TextField(
            modifier = Modifier
                .fillMaxWidth(),
            value = stateName,
            onValueChange = {
                onFormChanged(FormType.SHIPPING_COUNTRY, it)
            },
            label = { Text(text = label) },
            textStyle = MaterialTheme.typography.subtitle1,
            singleLine = true,
            trailingIcon = {
                IconButton(onClick = { expanded = true }) {
                    Icon(
                        imageVector = Icons.Filled.ArrowDropDown,
                        contentDescription = "",
                        tint = if (errorState) MaterialTheme.colors.error
                        else MaterialTheme.colors.onPrimary
                    )
                }
            },
            keyboardActions = KeyboardActions(onNext = {
                focusManager.moveFocus(
                    FocusDirection.Down
                )
            }),
            keyboardOptions = KeyboardOptions(
                imeAction = ImeAction.Done,
                keyboardType = KeyboardType.Text
            ),
            colors = TextFieldDefaults.textFieldColors(
                cursorColor = MaterialTheme.colors.secondary,
                textColor = MaterialTheme.colors.onPrimary,
                focusedLabelColor = if (errorState) MaterialTheme.colors.error
                else MaterialTheme.colors.secondary,
                focusedIndicatorColor = if (errorState) MaterialTheme.colors.error
                else MaterialTheme.colors.secondary,
                backgroundColor = MaterialTheme.colors.secondaryVariant
            )
        ) // state name label
        DropdownMenu(expanded = expanded, onDismissRequest = {
            expanded = false
        }) {
            statesMap.asIterable().iterator().forEach {
                val (key, value) = it
                DropdownMenuItem(
                    onClick = {
                        expanded = false
                        stateName = key
                        onFormChanged(FormType.SHIPPING_STATE, key)
                    },
                    modifier = Modifier.fillMaxWidth()
                ) {
                    Text(text = key)
                }
            }
        }

    }

    if (errorState && error) {
        ErrorMessages(modifier = modifier, message = "$label is required")
    }
  }
}

This is what it looks like, the state drop down and the zip code field are overlapping:

fields overlapping each other



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source