android - studio - ¿Cómo centrar varias vistas juntas utilizando ConstaintLayout?
relative layout android que es (5)
Fondo
Google ha anunciado un nuevo diseño llamado " ConstraintLayout " que se supone que es el diseño definitivo, que podría reemplazar a todos los diseños, mientras se mantiene plano (sin diseños internos) y tiene un mejor rendimiento.
El problema
El tema es que apenas veo tutoriales que me puedan ayudar en este asunto, aparte del video presentado en Google IO.
Lo que trato de hacer es que tengo un LinearLayout centrado verticalmente en otro diseño; conviértalos a ambos en un solo ConstraintLayout.
Después de todo, este es el propósito de este nuevo diseño ...
El diseño que deseo tratar se ve así:
Observe que las vistas en el centro solo están centradas verticalmente, y que las 2 TextViews están a la derecha de ImageView, que también está centrada verticalmente.
Todo esto funciona bien con RelativeLayout, que tiene el LinearLayout de las 2 TextViews, pero deseo saber cómo convertirlas en un solo ConstraintLayout.
Aquí hay una muestra XML de lo que he mostrado:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
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:minHeight="?attr/listPreferredItemHeightSmall">
<ImageView
android:id="@+id/appIconImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:layout_marginEnd="4dp"
android:layout_marginLeft="2dp"
android:layout_marginRight="4dp"
android:layout_marginStart="2dp"
android:adjustViewBounds="true"
android:src="@android:drawable/sym_def_app_icon"
tools:ignore="ContentDescription"/>
<LinearLayout
android:id="@+id/appDetailsContainer"
android:layout_width="0px"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toEndOf="@+id/appIconImageView"
android:layout_toLeftOf="@+id/overflowView"
android:layout_toRightOf="@+id/appIconImageView"
android:layout_toStartOf="@+id/overflowView"
android:orientation="vertical">
<TextView
android:id="@+id/appLabelTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:text="label"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textDirection="locale"
tools:ignore="HardcodedText,UnusedAttribute"/>
<TextView
android:id="@+id/appDescriptionTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:minLines="3"
android:text="description"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textDirection="locale"
tools:ignore="HardcodedText,UnusedAttribute"/>
</LinearLayout>
<ImageView
android:id="@+id/overflowView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:adjustViewBounds="true"
android:background="?attr/selectableItemBackground"
android:clickable="true"
android:padding="10dp"
app:srcCompat="@drawable/ic_more_vert_black_24dp"
tools:src="@drawable/ic_more_vert_black_24dp"
tools:ignore="ContentDescription"/>
<ImageView
android:id="@+id/isSystemAppImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignEnd="@+id/overflowView"
android:layout_alignLeft="@+id/overflowView"
android:layout_alignParentBottom="true"
android:layout_alignRight="@+id/overflowView"
android:layout_alignStart="@+id/overflowView"
android:adjustViewBounds="true"
android:scaleType="centerInside"
app:srcCompat="@drawable/ic_warning_black_24dp"
tools:ignore="ContentDescription"
tools:src="@drawable/ic_warning_black_24dp"/>
</RelativeLayout>
Lo que intenté
Intenté leer algunos artículos y ver algunos videos de Google:
- https://codelabs.developers.google.com/codelabs/constraint-layout/index.html#0
- https://www.youtube.com/watch?v=sO9aX87hq9c
- https://youtu.be/csaXml4xtN8?t=1693
Eso no ayudó, así que traté de usarlo, con la esperanza de descubrir cómo usarlo yo mismo. Pero no puedo averiguar cómo hacerlo. Intenté usar la función para convertir los diseños, pero esto crea un gran lío de vistas y pone márgenes adicionales que no quiero tener.
La pregunta
¿Cómo puedo convertir los 2 diseños en un solo ConstraintLayout?
Echa un vistazo a mi respuesta here .
ContraintLayout
contiene una característica - Chains
- que hace posible implementar lo que está pidiendo:
Las cadenas proporcionan un comportamiento grupal en un solo eje (horizontal o verticalmente).
Un conjunto de widgets se considera una cadena si se unen mediante una conexión bidireccional
Una vez que se crea una cadena, hay dos posibilidades:
- Difundir los elementos en el espacio disponible.
- Una cadena también se puede "empaquetar", en ese caso los elementos se agrupan
En cuanto a su caso, tendrá que empaquetar su label
y description
TextViews y centrarlas en su padre verticalmente:
(Asegúrese de usar una versión de ConstraintLayout
que admita cadenas)
<?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/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="16dp"
android:text="TextView"
app:layout_constraintBottom_toTopOf="@+id/button"
app:layout_constraintLeft_toRightOf="@+id/imageView2"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainPacked="true"/>
<TextView
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="Button/nMkay"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="@+id/imageView2"
app:layout_constraintTop_toBottomOf="@+id/textView"/>
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginTop="16dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@mipmap/ic_launcher"/>
<ImageView
android:id="@+id/imageView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@mipmap/ic_launcher"/>
<ImageView
android:id="@+id/imageView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:layout_marginEnd="16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:srcCompat="@mipmap/ic_launcher"/>
</android.support.constraint.ConstraintLayout>
EDITAR: Esta respuesta había sido escrita antes de que las cadenas estuvieran disponibles. Utilice cadenas ahora, vea la respuesta anterior: https://.com/a/40102296/1402641
Por ahora, creo que su única opción sería envolver las dos vistas de texto en otro diseño, probablemente el diseño lineal se adapte mejor a esta situación.
Pero el equipo detrás del diseño de restricciones dijo que desea introducir "contenedores virtuales", que sirven exactamente para este caso de uso: agrupa dos o más vistas y establece una restricción (como centrar verticalmente) en el contenedor. La idea es que no se trata de un diseño anidado completo dentro del diseño de restricciones, sino de algo que el diseño de restricciones utiliza para posicionar a sus hijos, por lo tanto, debería proporcionar un mejor rendimiento que el anidamiento.
Lo mencionan en su charla de E / S (vinculada a la hora exacta). Así que supongo que estar atentos.
Eche un vistazo a mi ejemplo (los componentes del Centro en ConstraintLayout )
Por ahora podría centrar la "imagen" (restringir izquierda-arriba-abajo), restringir "etiqueta" arriba a "imagen" arriba, restringir "descripción" arriba a "etiqueta" abajo. En el siguiente ejemplo, he combinado la altura del botón con dos vistas de texto a la derecha (que es su caso). Otras vistas de texto están restringidas como en el enlace de arriba.
ACTUALIZACIÓN: Respondiendo a tu comentario a continuación:
He instalado tu aplicación y esto es solo lo que puedo pensar actualmente. Como se trata de un diseño de ViewHolder, layout_height puede configurarse como wrap_content, o puede corregirlo si lo desea. Puedo enviarte XML si quieres, no quiero inundar la respuesta.
La restricción izquierda superior de TextView está restringida a la restricción derecha de ImageView. Además, la restricción top TextView -> top está restringida a la parte superior del contenedor, por lo que es correcto. TextView inferior está restringido a la parte inferior del contenedor. Las vistas de texto en el medio están restringidas para coincidir con el ancho de TextView superior y no tienen conexión con ImageView.
Establezca app:layout_constraintVertical_bias="0.5"
en las vistas que deben centrarse verticalmente, el atributo de sesgo solo funciona si especifica las restricciones para los límites (por ejemplo, superior e inferior para el sesgo vertical, izquierda y derecha para el sesgo horizontal)
Un ejemplo:
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/constraintLayout">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="@id/constraintLayout"
app:layout_constraintBottom_toBottomOf="@id/constraintLayout"
app:layout_constraintVertical_bias="0.5" />
</android.support.constraint.ConstraintLayout>
Lo tengo funcionando en mi diseño aquí: https://github.com/hidroh/tldroid/blob/master/app/src/main/res/layout/activity_main.xml , diseño bastante similar, aunque posiciono las cosas en 1 / 3º de altura de pantalla.
Para centrar algo vertical u horizontalmente, establezca una restricción opuesta en el diseño.
Centrado verticalmente
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
Centrado horizontalmente
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"