¿Cómo alinear y centrar verticalmente objetos en un diseño de restricción? Es posible alinear vertical u horizontalmente, pero no he encontrado una manera de centrar al mismo tiempo además de restringir las vistas entre dos líneas de cuadrícula.
Centro de alineación vertical:

Parece que el centrado es un gran problema con el diseño de restricciones que me obliga a volver al diseño relativo para "centerInParent", "centerVertical" y "centerHorizontal".
Me gustaría crear el diseño en caja en rojo usando el diseño de restricción:

Desafortunadamente, la única forma que encontré sin usar dos líneas de cuadrícula es con diseños lineales y relativos anidados (¡se suponía que el diseño de restricciones resolvía este escenario exacto!).
Diseño con diseño relativo y lineal:
<RelativeLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
app:layout_constraintTop_toBottomOf="@id/user_points"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent">
<LinearLayout
android:id="@+id/stat_1_layout"
android:layout_width="60dp"
android:layout_height="wrap_content"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp"
android:layout_centerVertical="true"
android:layout_toLeftOf="@+id/divider_1"
android:orientation="vertical">
<TextView
android:id="@+id/stat_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:gravity="center_horizontal"
android:text="10"
android:textSize="16dp"
android:textColor="@color/textSecondaryDark"
android:maxLines="1"/>
<TextView
android:id="@+id/stat_detail_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:gravity="center"
android:text="Streak"
android:textSize="8sp"
android:textColor="@color/textSecondary"
android:maxLines="1"/>
</LinearLayout>
<View
android:id="@+id/divider_1"
android:layout_width="1dp"
android:layout_height="38dp"
android:layout_toLeftOf="@+id/stat_2_layout"
android:background="@drawable/linedivider"/>
<LinearLayout
android:id="@+id/stat_2_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="18dp"
android:layout_marginRight="18dp"
android:layout_centerInParent="true"
android:orientation="vertical">
<TextView
android:id="@+id/stat_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:gravity="center_horizontal"
android:text="243"
android:textSize="16dp"
android:textColor="@color/textSecondaryDark"
android:maxLines="1"/>
<TextView
android:id="@+id/stat_detail_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:gravity="center"
android:text="Calories Burned"
android:textSize="8sp"
android:textColor="@color/textSecondary"
android:maxLines="1"/>
</LinearLayout>
<View
android:id="@+id/divider_2"
android:layout_width="1dp"
android:layout_height="38dp"
android:layout_toRightOf="@+id/stat_2_layout"
android:background="@drawable/linedivider"/>
<LinearLayout
android:id="@+id/stat_3_layout"
android:layout_width="60dp"
android:layout_height="wrap_content"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp"
android:layout_toRightOf="@+id/divider_2"
android:layout_centerVertical="true"
android:orientation="vertical">
<TextView
android:id="@+id/stat_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:gravity="center_horizontal"
android:text="3200"
android:textSize="16dp"
android:textColor="@color/textSecondaryDark"
android:maxLines="1"/>
<TextView
android:id="@+id/stat_detail_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:gravity="center"
android:text="Steps"
android:textSize="8sp"
android:textColor="@color/textSecondary"
android:maxLines="1"/>
</LinearLayout>
</RelativeLayout>

Respuestas:
Es posible establecer la vista alineada al centro como un ancla para otras vistas. En el siguiente ejemplo, "@ + id / stat_2" centrado horizontalmente en padre y sirve como un ancla para otras vistas en este diseño.
<android.support.constraint.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_height="match_parent"> <TextView android:id="@+id/stat_1" android:layout_width="80dp" android:layout_height="wrap_content" android:layout_marginEnd="8dp" android:gravity="center" android:maxLines="1" android:text="10" android:textColor="#777" android:textSize="22sp" app:layout_constraintTop_toTopOf="@+id/stat_2" app:layout_constraintEnd_toStartOf="@+id/divider_1" /> <TextView android:id="@+id/stat_detail_1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Streak" android:textColor="#777" android:textSize="12sp" app:layout_constraintTop_toBottomOf="@+id/stat_1" app:layout_constraintStart_toStartOf="@+id/stat_1" app:layout_constraintEnd_toEndOf="@+id/stat_1" /> <View android:id="@+id/divider_1" android:layout_width="1dp" android:layout_height="0dp" android:layout_marginEnd="16dp" android:background="#ccc" app:layout_constraintTop_toTopOf="@+id/stat_2" app:layout_constraintEnd_toStartOf="@+id/stat_2" app:layout_constraintBottom_toBottomOf="@+id/stat_detail_2" /> <TextView android:id="@+id/stat_2" android:layout_width="80dp" android:layout_height="wrap_content" android:gravity="center" android:maxLines="1" android:text="243" android:textColor="#777" android:textSize="22sp" app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintBottom_toBottomOf="parent" /> <TextView android:id="@+id/stat_detail_2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:maxLines="1" android:text="Calories Burned" android:textColor="#777" android:textSize="12sp" app:layout_constraintTop_toBottomOf="@+id/stat_2" app:layout_constraintStart_toStartOf="@+id/stat_2" app:layout_constraintEnd_toEndOf="@+id/stat_2" /> <View android:id="@+id/divider_2" android:layout_width="1dp" android:layout_height="0dp" android:layout_marginStart="16dp" android:background="#ccc" app:layout_constraintBottom_toBottomOf="@+id/stat_detail_2" app:layout_constraintStart_toEndOf="@+id/stat_2" app:layout_constraintTop_toTopOf="@+id/stat_2" /> <TextView android:id="@+id/stat_3" android:layout_width="80dp" android:layout_height="wrap_content" android:layout_marginStart="8dp" android:gravity="center" android:maxLines="1" android:text="3200" android:textColor="#777" android:textSize="22sp" app:layout_constraintTop_toTopOf="@+id/stat_2" app:layout_constraintStart_toEndOf="@+id/divider_2" /> <TextView android:id="@+id/stat_detail_3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:maxLines="1" android:text="Steps" android:textColor="#777" android:textSize="12sp" app:layout_constraintTop_toBottomOf="@+id/stat_3" app:layout_constraintStart_toStartOf="@+id/stat_3" app:layout_constraintEnd_toEndOf="@+id/stat_3" /> </android.support.constraint.ConstraintLayout>Así es como funciona en el teléfono inteligente más pequeño (3.7 Nexus One de 480 x 800) frente al teléfono inteligente más grande (5.5 1440 x 2560 Pixel XL)
fuente
Si tiene un
ConstraintLayoutniño con algún tamaño y un niñoViewcon un tamaño más pequeño, puede lograr el centrado restringiendo los dos bordes del niño a los mismos dos bordes del padre. Es decir, puedes escribir:app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent"o
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent"Debido a que la vista es más pequeña, estas restricciones son imposibles. Pero
ConstraintLayouthará lo mejor que pueda, y cada restricción "tirará" de la vista secundaria por igual, centrándola así.Este concepto funciona con cualquier vista de destino, no solo con la principal.
Actualizar
A continuación se muestra XML que logra la interfaz de usuario deseada sin anidamiento de vistas y sin
Guidelines (aunque las pautas no son inherentemente malas).<android.support.constraint.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_height="wrap_content" android:background="#eee"> <TextView android:id="@+id/title1" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginBottom="12dp" android:gravity="center" android:textColor="#777" android:textSize="22sp" android:text="10" app:layout_constraintTop_toTopOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toLeftOf="@+id/divider1" app:layout_constraintBottom_toBottomOf="parent"/> <TextView android:id="@+id/label1" android:layout_width="0dp" android:layout_height="wrap_content" android:gravity="center" android:textColor="#777" android:textSize="12sp" android:text="Streak" app:layout_constraintTop_toBottomOf="@+id/title1" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toLeftOf="@+id/divider1"/> <View android:id="@+id/divider1" android:layout_width="1dp" android:layout_height="55dp" android:layout_marginTop="12dp" android:layout_marginBottom="12dp" android:background="#ccc" app:layout_constraintTop_toTopOf="parent" app:layout_constraintLeft_toRightOf="@+id/title1" app:layout_constraintRight_toLeftOf="@+id/title2" app:layout_constraintBottom_toBottomOf="parent"/> <TextView android:id="@+id/title2" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginBottom="12dp" android:gravity="center" android:textColor="#777" android:textSize="22sp" android:text="243" app:layout_constraintTop_toTopOf="parent" app:layout_constraintLeft_toRightOf="@+id/divider1" app:layout_constraintRight_toLeftOf="@+id/divider2" app:layout_constraintBottom_toBottomOf="parent"/> <TextView android:id="@+id/label2" android:layout_width="0dp" android:layout_height="wrap_content" android:gravity="center" android:textColor="#777" android:textSize="12sp" android:text="Calories Burned" app:layout_constraintTop_toBottomOf="@+id/title2" app:layout_constraintLeft_toRightOf="@+id/divider1" app:layout_constraintRight_toLeftOf="@+id/divider2"/> <View android:id="@+id/divider2" android:layout_width="1dp" android:layout_height="55dp" android:layout_marginTop="12dp" android:layout_marginBottom="12dp" android:background="#ccc" app:layout_constraintTop_toTopOf="parent" app:layout_constraintLeft_toRightOf="@+id/title2" app:layout_constraintRight_toLeftOf="@+id/title3" app:layout_constraintBottom_toBottomOf="parent"/> <TextView android:id="@+id/title3" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginBottom="12dp" android:gravity="center" android:textColor="#777" android:textSize="22sp" android:text="3200" app:layout_constraintTop_toTopOf="parent" app:layout_constraintLeft_toRightOf="@+id/divider2" app:layout_constraintRight_toRightOf="parent" app:layout_constraintBottom_toBottomOf="parent"/> <TextView android:id="@+id/label3" android:layout_width="0dp" android:layout_height="wrap_content" android:gravity="center" android:textColor="#777" android:textSize="12sp" android:text="Steps" app:layout_constraintTop_toBottomOf="@+id/title3" app:layout_constraintLeft_toRightOf="@+id/divider2" app:layout_constraintRight_toRightOf="parent"/> </android.support.constraint.ConstraintLayout>fuente
Puede ser que no entendiera completamente el problema, pero centrar todas las vistas dentro de un ConstraintLayout parece muy simple. Esto es lo que usé:
<android.support.constraint.ConstraintLayout 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" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center">¡Las dos últimas líneas funcionaron!
fuente
<TextView android:id="@+id/tvName" style="@style/textViewBoldLarge" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:text="Welcome" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent"/>fuente
Puede centrar fácilmente varias cosas creando una cadena. Funciona tanto en vertical como en horizontal
Enlace a documentación oficial sobre cadenas
Editar para responder al comentario :
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.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_height="match_parent" > <TextView android:id="@+id/first_score" android:layout_width="60dp" android:layout_height="wrap_content" android:text="10" app:layout_constraintEnd_toStartOf="@+id/second_score" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="@+id/second_score" app:layout_constraintBottom_toTopOf="@+id/subtitle" app:layout_constraintHorizontal_chainStyle="spread" app:layout_constraintVertical_chainStyle="packed" android:gravity="center" /> <TextView android:id="@+id/subtitle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Subtitle" app:layout_constraintTop_toBottomOf="@+id/first_score" app:layout_constraintBottom_toBottomOf="@+id/second_score" app:layout_constraintStart_toStartOf="@id/first_score" app:layout_constraintEnd_toEndOf="@id/first_score" /> <TextView android:id="@+id/second_score" android:layout_width="60dp" android:layout_height="120sp" android:text="243" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toStartOf="@+id/thrid_score" app:layout_constraintStart_toEndOf="@id/first_score" app:layout_constraintTop_toTopOf="parent" android:gravity="center" /> <TextView android:id="@+id/thrid_score" android:layout_width="60dp" android:layout_height="wrap_content" android:text="3200" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@id/second_score" app:layout_constraintTop_toTopOf="@id/second_score" app:layout_constraintBottom_toBottomOf="@id/second_score" android:gravity="center" /> </android.support.constraint.ConstraintLayout>Usted tiene la cadena horizontal:
first_score <=> second_score <=> third_score.second_scoreestá centrado verticalmente. Las otras puntuaciones se centran verticalmente de acuerdo con él.Definitivamente puede crear una cadena vertical
first_score <=> subtitley centrarla de acuerdo consecond_scorefuente
Mostrándolo gráficamente.
El centrado en el padre se realiza restringiendo ambos lados al padre. Puede restringir objetos adicionales fuera del objeto centrado.
Nota. Cada flecha representa un atributo "app: layout_constraintXXX_toYYY =". (6 en la foto)
fuente
También tenía un requisito similar. Quería tener un contenedor en el centro de la pantalla y dentro del contenedor hay muchas vistas. A continuación se muestra el código de diseño xml. Aquí estoy usando un diseño de restricción anidado para crear un contenedor en el centro de la pantalla.
<androidx.constraintlayout.widget.ConstraintLayout 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" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/gradient_background" tools:context=".activities.AppInfoActivity"> <ImageView android:id="@+id/ivClose" android:layout_width="30dp" android:layout_height="30dp" android:layout_marginStart="20dp" android:layout_marginTop="20dp" android:src="@drawable/ic_round_close_24" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <androidx.constraintlayout.widget.ConstraintLayout android:layout_width="300dp" android:layout_height="300dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.5"> <ImageView android:id="@+id/ivAppIcon" android:layout_width="100dp" android:layout_height="100dp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:srcCompat="@drawable/dead" /> <TextView android:id="@+id/tvAppName" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Birds Shooter Plane" android:textAlignment="center" android:textSize="30sp" android:textStyle="bold" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/ivAppIcon" /> <TextView android:id="@+id/tvAppVersion" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Version : 1.0" android:textAlignment="center" android:textSize="12sp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/tvAppName" /> <TextView android:id="@+id/tvDevelopedBy" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="25dp" android:text="Developed by" android:textAlignment="center" android:textSize="12sp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/tvAppVersion" /> <TextView android:id="@+id/tvDevelopedName" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:text="K Pradeep Kumar Reddy" android:textAlignment="center" android:textSize="14sp" android:textStyle="bold" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/tvDevelopedBy" /> <TextView android:id="@+id/tvContact" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:text="Contact : [email protected]" android:textAlignment="center" android:textSize="12sp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/tvDevelopedName" /> <TextView android:id="@+id/tvCheckForUpdate" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="25dp" android:text="@string/check_for_update" android:textAlignment="center" android:textSize="14sp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/tvContact" /> </androidx.constraintlayout.widget.ConstraintLayout></androidx.constraintlayout.widget.ConstraintLayout>
Aquí está la captura de pantalla del diseño.
Otra solución es eliminar el diseño de restricción anidado y agregar el atributo constraint_vertical_bias = 0.5 al elemento superior en el centro del diseño. Creo que esto se llama encadenamiento de puntos de vista.
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout 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" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/gradient_background" tools:context=".activities.AppInfoActivity"> <ImageView android:id="@+id/ivClose" android:layout_width="30dp" android:layout_height="30dp" android:layout_marginStart="20dp" android:layout_marginTop="20dp" android:src="@drawable/ic_round_close_24" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <ImageView android:id="@+id/ivAppIcon" android:layout_width="100dp" android:layout_height="100dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.5" app:srcCompat="@drawable/dead" /> <TextView android:id="@+id/tvAppName" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/app_display_name" android:textAlignment="center" android:textSize="30sp" android:textStyle="bold" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/ivAppIcon" /> <TextView android:id="@+id/tvAppVersion" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/version" android:textAlignment="center" android:textSize="12sp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/tvAppName" /> <TextView android:id="@+id/tvDevelopedBy" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="25dp" android:text="@string/developed_by" android:textAlignment="center" android:textSize="12sp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/tvAppVersion" /> <TextView android:id="@+id/tvDevelopedName" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:text="@string/developer_name" android:textAlignment="center" android:textSize="14sp" android:textStyle="bold" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/tvDevelopedBy" /> <TextView android:id="@+id/tvContact" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:text="@string/developer_email" android:textAlignment="center" android:textSize="12sp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/tvDevelopedName" /> <TextView android:id="@+id/tvCheckForUpdate" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="25dp" android:text="@string/check_for_update" android:textAlignment="center" android:textSize="14sp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/tvContact" /> </androidx.constraintlayout.widget.ConstraintLayout>Aquí está la captura de pantalla del diseño.
fuente