Search code examples
androidandroid-jetpack-composealignment

Alignment between views in Jetpack Compose


I am migrating the Android XML views to Jetpack Compose. There are two Text and one Switch, that must consider this rules.

  • My first Text must be aligned to top and start.
  • The Switch must be aligned to top and end. In addition, this Text and the Switch must be have the same height and aligned vertically.
  • The other Text, must be placed below first Text and it musn't use the space below Switch.
@Composable
fun ComposeConstraintLayout() {
    Row(
        modifier = Modifier
            .fillMaxSize()
            .background(color = Color(red = 0xAA, green = 0xFF, blue = 0xCC))
            .padding(16.dp),
        verticalAlignment = Alignment.Top,
    ) {
        Column(
            modifier = Modifier
                .fillMaxHeight()
                .weight(1f)
                .padding(start = 16.dp),
        ) {
            Text(
                text = "Enable your option",
                fontSize = 20.sp,
                color = Color.Black,
                modifier = Modifier
                    .fillMaxWidth()
                    .background(color = Color(red = 0x00, green = 0xAA, blue = 0x00))
                    .padding(end = 8.dp),
            )

            Text(
                text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.",
                fontSize = 14.sp,
                color = Color.Black,
                modifier = Modifier
                    .fillMaxWidth()
                    .background(color = Color(red = 0x00, green = 0xEE, blue = 0xEE))
                    .padding(end = 8.dp),
            )
        }

        Switch(
            checked = false,
            onCheckedChange = {},
            modifier = Modifier
                .align(Alignment.Top)
                .background(color = Color(red = 0xA3, green = 0xD4, blue = 0x00)),
        )
    }

The result isn't ok.

enter image description here

The result that I want to find.

enter image description here

As I am migrating from Android XML views to Jetpack Compose I paste the code too

<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_margin="10dp"
    android:background="#AAFFCC"
    android:layout_height="match_parent">

    <androidx.appcompat.widget.SwitchCompat
        android:id="@+id/switchRight"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="#AA0000"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintEnd_toEndOf="parent" />

    <TextView
        android:id="@+id/tv1"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:gravity="center_vertical"
        android:text="Enable your option"
        android:background="#00AA00"
        app:layout_constraintBottom_toBottomOf="@+id/switchRight"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/switchRight"
        app:layout_constraintTop_toTopOf="@+id/switchRight" />

    <TextView
        android:id="@+id/tv2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:background="#A3D400"
        app:layout_constraintTop_toBottomOf="@+id/tv1"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/switchRight"
        android:text="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur."

</androidx.constraintlayout.widget.ConstraintLayout>

Thanks


Solution

  • enter image description here

    You can achieve this by using ConstraintLayout. Checkout the below code. You can make minor adjustments based on your requirements. Key parts to highlight: look at the height, width of the title and also horizontal chain and barrier usage.

    @Composable
    fun ComposeConstraintLayout() {
        val constraints = ConstraintSet {
            val title = createRefFor("title")
            val body = createRefFor("body")
            val switch = createRefFor("switch")
            val barrier = createStartBarrier(switch)
            constrain(switch) {
                top.linkTo(parent.top)
                end.linkTo(parent.end)
                start.linkTo(title.end)
            }
            constrain(title) {
                top.linkTo(switch.top)
                bottom.linkTo(switch.bottom)
                start.linkTo(parent.start)
                end.linkTo(barrier)
                width = Dimension.fillToConstraints
                height = Dimension.fillToConstraints
            }
            constrain(body) {
                start.linkTo(title.start)
                top.linkTo(title.bottom)
                end.linkTo(barrier)
                width = Dimension.fillToConstraints
    
            }
            createHorizontalChain(title, switch, chainStyle = ChainStyle.SpreadInside)
        }
    
        ConstraintLayout(
            constraintSet = constraints,
            modifier = Modifier
                .fillMaxSize()
                .background(color = Color(red = 0xAA, green = 0xFF, blue = 0xCC)),
        ) {
            Column(
                modifier = Modifier
                    .background(color = Color(red = 0x00, green = 0xAA, blue = 0x00))
                    .layoutId("title"),
                verticalArrangement = Arrangement.Center,
                horizontalAlignment = Alignment.Start,
            ) {
                Text(
                    text = "Enable your option",
                    Modifier.padding(8.dp),
                    fontSize = 20.sp,
                    color = Color.Black,
                )
            }
            Switch(
                modifier = Modifier
                    .background(color = Color(red = 0xA3, green = 0xD4, blue = 0x00))
                    .layoutId("switch"),
                checked = false,
                onCheckedChange = {},
            )
            Column(
                modifier = Modifier
                    .background(color = Color(red = 0x00, green = 0xEE, blue = 0xEE))
                    .layoutId("body"),
                verticalArrangement = Arrangement.Center,
                horizontalAlignment = Alignment.Start,
            ) {
                Text(
                    text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.",
                    Modifier.padding(8.dp),
                    fontSize = 14.sp,
                    color = Color.Black,
                )
            }
        }
    }