如何在约束布局中居中元素 android

how to centre elements in a constraint layout android

我想在约束布局中将元素居中。我添加了一个新的文本视图 Turns charger...,它保存在 sleep when inactive 文本视图下方,这导致它在卡片视图

的顶部展开并清空间隙

有什么方法可以让所有元素居中吗?

<androidx.cardview.widget.CardView
            android:id="@+id/cvTapToWake"
            style="@style/Tile"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:visibility="visible"
            android:layout_marginHorizontal="24dp"
            android:clipChildren="false"
            android:clipToPadding="false"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/cvLockCharger">

            <androidx.constraintlayout.widget.ConstraintLayout
                android:id="@+id/tapToWake"
                style="@style/Tile"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@color/white_screen_bg"
                android:clipChildren="false"
                android:clipToPadding="false"

                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/lockChargerButtons"
                app:layout_goneMarginTop="32dp">

                <ImageView
                    android:id="@+id/ivTapToAwake"
                    android:layout_width="32dp"
                    android:layout_height="32dp"
                    android:layout_marginVertical="26dp"
                    android:layout_marginStart="24dp"
                    android:src="@drawable/ic_wake"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toTopOf="parent" />

                <TextView
                    android:id="@+id/tvTapToWake"
                    style="@style/Text.Medium.Bold"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:layout_marginStart="@dimen/text_margin"
                    android:text="@string/tap_to_wake"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintStart_toEndOf="@+id/ivTapToAwake"
                    app:layout_constraintTop_toTopOf="parent" />

                <androidx.appcompat.widget.SwitchCompat
                    android:id="@+id/tapToAwakeSwitch"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignParentEnd="true"
                    android:layout_marginEnd="16dp"
                    android:theme="@style/SwitchCompatTheme"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintTop_toTopOf="parent"
                    tools:checked="true" />

                <TextView
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="8dp"
                    android:paddingBottom="16dp"
                    android:text="@string/turn_off_screen"
                    app:layout_constraintStart_toStartOf="@+id/tvTapToWake"
                    app:layout_constraintEnd_toEndOf="@+id/tapToAwakeSwitch"
                    app:layout_constraintTop_toBottomOf="@+id/tvTapToWake" />

            </androidx.constraintlayout.widget.ConstraintLayout>
        </androidx.cardview.widget.CardView>

这是现在的样子,顶部有空白 space

能否建议我如何删除顶部的空白 space 并将所有元素居中

谢谢 R

要使两个 TextViews 垂直居中,您需要添加相互垂直约束,并将它们都约束到最近的父项的垂直边缘。通过:

  • 正在将 app:layout_constraintBottom_toBottomOf="parent"tvTapToWake 转移到底部 TextView
  • app:layout_constraintBottom_toTopOf="@+id/bottomTV" 添加到 tvTapToWake

并且您已经添加了其他两个约束。

但这会使底部 TextView 与 RHS 开关相交。您可能通过将底部 TextView 约束从 app:layout_constraintEnd_toEndOf="@+id/tapToAwakeSwitch" 修改为 app:layout_constraintEnd_toStartOf="@+id/tapToAwakeSwitch"

来解决此问题

应用这个:

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView android:id="@+id/cvTapToWake"
    style="@style/Tile"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:visibility="visible"
    android:layout_marginHorizontal="24dp"
    android:clipChildren="false"
    android:clipToPadding="false"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/cvLockCharger"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/tapToWake"
        style="@style/Tile"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/white_screen_bg"
        android:clipChildren="false"
        android:clipToPadding="false"

        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/lockChargerButtons"
        app:layout_goneMarginTop="32dp">

        <ImageView
            android:id="@+id/ivTapToAwake"
            android:layout_width="32dp"
            android:layout_height="32dp"
            android:layout_marginVertical="26dp"
            android:layout_marginStart="24dp"
            android:src="@drawable/ic_wake"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@+id/tvTapToWake"
            style="@style/Text.Medium.Bold"
            android:layout_width="wrap_content"
            app:layout_constraintBottom_toTopOf="@+id/bottomTV"
            android:layout_height="match_parent"
            android:layout_marginStart="@dimen/text_margin"
            android:text="@string/tap_to_wake"
            app:layout_constraintStart_toEndOf="@+id/ivTapToAwake"
            app:layout_constraintTop_toTopOf="parent" />

        <androidx.appcompat.widget.SwitchCompat
            android:id="@+id/tapToAwakeSwitch"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentEnd="true"
            android:layout_marginEnd="16dp"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            android:theme="@style/SwitchCompatTheme"
            app:layout_constraintEnd_toEndOf="parent"
            tools:checked="true" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:id="@+id/bottomTV"
            android:paddingBottom="16dp"
            android:text="@string/turn_off_screen"
            app:layout_constraintEnd_toStartOf="@+id/tapToAwakeSwitch"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="@+id/tvTapToWake"
            app:layout_constraintEnd_toEndOf="@+id/tapToAwakeSwitch"
            app:layout_constraintTop_toBottomOf="@+id/tvTapToWake" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>

解决此问题的另一种方法是通过将 app:layout_constraintBaseline_toBaselineOf="@+id/tvTapToWake" 添加到 tvTapToWake 并将开关基线对齐到顶部 TextView,并从开关中删除垂直约束:

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView android:id="@+id/cvTapToWake"
    style="@style/Tile"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:visibility="visible"
    android:layout_marginHorizontal="24dp"
    android:clipChildren="false"
    android:clipToPadding="false"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/cvLockCharger"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/tapToWake"
        style="@style/Tile"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/white_screen_bg"
        android:clipChildren="false"
        android:clipToPadding="false"

        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/lockChargerButtons"
        app:layout_goneMarginTop="32dp">

        <ImageView
            android:id="@+id/ivTapToAwake"
            android:layout_width="32dp"
            android:layout_height="32dp"
            android:layout_marginVertical="26dp"
            android:layout_marginStart="24dp"
            android:src="@drawable/ic_wake"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@+id/tvTapToWake"
            style="@style/Text.Medium.Bold"
            android:layout_width="wrap_content"
            app:layout_constraintBottom_toTopOf="@+id/bottomTV"
            android:layout_height="match_parent"
            android:layout_marginStart="@dimen/text_margin"
            android:text="@string/tap_to_wake"
            app:layout_constraintStart_toEndOf="@+id/ivTapToAwake"
            app:layout_constraintTop_toTopOf="parent" />

        <androidx.appcompat.widget.SwitchCompat
            android:id="@+id/tapToAwakeSwitch"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintBaseline_toBaselineOf="@+id/tvTapToWake"
            android:layout_alignParentEnd="true"
            android:layout_marginEnd="16dp"
            android:theme="@style/SwitchCompatTheme"
            app:layout_constraintEnd_toEndOf="parent"
            tools:checked="true" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:id="@+id/bottomTV"
            android:paddingBottom="16dp"
            android:text="@string/turn_off_screen"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="@+id/tvTapToWake"
            app:layout_constraintEnd_toEndOf="@+id/tapToAwakeSwitch"
            app:layout_constraintTop_toBottomOf="@+id/tvTapToWake" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>

假设您希望所有文本都经过开关底部:

您的开关是顶行中最高的东西,因此您应该将图像视图和第一个文本视图垂直居中,因此将这两个更改为将顶部和底部约束限制在开关的顶部和底部,而不是parent的。此外,从您的图像视图中删除 marginVertical,因为这将阻止它在开关上居中。

然后移除开关的底部约束,使其不会在 parent 上垂直居中。将第二个文本视图的顶部限制在开关的底部,因为那是顶行小部件的最低点。

直接在 ConstraintLayout 上设置顶部和底部内边距以补偿移除的内部垂直边距。