android - texto - poner una imagen en la parte inferior html
RestricciónLayout Cadenas y texto Elipsis+Imagen a la derecha (4)
ACTUALIZACIÓN JULIO 2018:
Si está utilizando ConstraintLayout 1.1.0
, la propiedad correcta a usar es app:layout_constrainedWidth="true"
en lugar de la app:layout_constraintWidth_default="wrap"
antigua app:layout_constraintWidth_default="wrap"
(y la contraparte de altura). Ver respuesta actualizada.
ACTUALIZACIÓN NOVIEMBRE 2017:
Si está utilizando ConstraintLayout 1.0.0
estable (o superior) (1.0.2 en este momento), consulte la Respuesta actualizada para obtener una solución más sencilla sin la necesidad de anidar diseños.
Pregunta original:
Utilizando ConstraintLayouts-Beta3
lanzado el 3 de noviembre de 2016. ( source )
Estoy tratando de hacer lo siguiente:
| | |<-[TextView]<->[ImageView] -----------> | | |
Lo que he logrado con un diseño como este:
<TextView
android:id="@+id/textView"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toLeftOf="@+id/caret"
app:layout_constraintHorizontal_bias="0.0"
android:text="Some Text"
android:textAlignment="viewStart"
android:gravity="start" />
<ImageView
android:id="@+id/caret"
android:layout_width="wrap_content"
android:layout_height="8dp"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintLeft_toRightOf="@+id/textView"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="@+id/textView"
app:layout_constraintBottom_toBottomOf="@+id/textView"
app:layout_constraintHorizontal_bias="0.0"
android:contentDescription=""
app:srcCompat="@drawable/ic_selection"
android:layout_marginStart="8dp"/>
Esto se ve bien, pero cuando el texto es más largo que el espacio disponible ...
| | |<-[TextView Larger Than The Space Avail]| | |
La vista de texto tiene un estilo que especifica estos:
<item name="android:lines">1</item>
<item name="android:maxLines">1</item>
<item name="android:ellipsize">end</item>
Por lo tanto, debería funcionar, pero no estoy seguro de qué restricciones necesito para que la imagen se deslice hasta la derecha y luego se detenga allí y deje que la vista de texto entienda que no hay más espacio.
¿Qué me estoy perdiendo?
Nota: si configuro el ancho de la vista de texto en 0dp, funciona, pero la imagen siempre está a la derecha (el sesgo horizontal parece ignorarse)
Nota2: También he intentado esto con beta2, de hecho, parece que Beta3 tiene un error en el editor visual .
ACTUALIZACIÓN : intenté replicar esto en Xcode / AutoLayout:
Así es como se ve con un texto corto.
Ahora con el mismo diseño, acabo de escribir un texto largo en la vista de texto ...
Como puede ver, la restricción del camino (derecha) para la vista de imagen dice: está a 8 o más puntos del margen derecho.
También está anclado a la izquierda de la etiqueta (textView).
Por lo que acabo de aprender de Twitter, es posible que esto no sea posible en ConstraintLayout de Android en este momento: Source
ACTUALIZACIÓN JULIO 2018:
Si está utilizando ConstraintLayout 1.1.0
, la propiedad correcta a usar es app:layout_constrainedWidth="true"
en lugar de la app:layout_constraintWidth_default="wrap"
antigua app:layout_constraintWidth_default="wrap"
(y la contraparte de altura)
ACTUALIZACIÓN NOVIEMBRE 2017
Estoy usando Constraint Layouts 1.0.2 y he encontrado una solución menos anidada usando app:layout_constraintWidth_default="wrap"
(una propiedad que se introdujo en 1.0.0 pero la app:layout_constraintWidth_default="wrap"
Beta que esta publicación estaba usando no tenía).
En lugar del FrameLayout
que contiene un LinearLayout
, ahora puedes eliminar todo eso y tenerlo de esta manera:
<android.support.constraint.ConstraintLayout
android:id="@+id/new_way_container"
android:layout_height="wrap_content"
android:layout_width="0dp" // THIS GUY USES ALL THE WIDTH.
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:ellipsize="end"
android:id="@+id/some_text"
android:layout_height="wrap_content"
android:layout_width="0dp" //NO WRAP CONTENT, USE CONSTRAINTS
android:lines="1"
android:maxLines="1"
app:layout_constraintEnd_toStartOf="@+id/disclosure_arrow"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintHorizontal_chainStyle="packed" //CHAIN IT for biasing.
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_default="wrap" /> //THIS IS THE KEY THAT WILL CAUSE THIS TO WORK
<ImageView
android:id="@+id/disclosure_arrow"
android:layout_height="wrap_content"
android:layout_width="10dp"
app:layout_constraintBottom_toTopOf="@id/some_text"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/some_text"
app:layout_constraintTop_toBottomOf="@id/some_text"
app:srcCompat="@drawable/your_vector_image" />
</android.support.constraint.ConstraintLayout>
Esto efectivamente hace exactamente lo que quiero, sin trucos ni pautas ni tamaños codificados.
TextView utilizará el tamaño provisto por las Restricciones (lo que en circunstancias normales significaría que sería incorrecto o crecería más allá del ''padre''), pero gracias al nuevo atributo, esas restricciones pueden doblarse o romperse si el El contenido es más pequeño / más grande.
Tengo que decir que funciona mucho mejor que las prioridades de iOS. (Al menos es mucho más fácil de entender para mí). Pulgares arriba para Google en este caso :)
ANTIGUA RESPUESTA (en caso de que todavía la necesites).
Basándome en la respuesta de Nicolas Roard, iba a crear un contenedor personalizado que básicamente calcularía el espacio disponible y establecería por programación el maxWidth en el TextView. En lugar de agregar otra clase, prueba de unidad, posible conjunto de errores, etc., al proyecto, probé un método un poco menos eficiente para anidar un par de diseños; considerando que hemos estado anidando diseños desde la era del amanecer y que esto no estará en ninguna vista de la lista de desplazamiento o que se moverá demasiado (o en absoluto) y que estoy usando ConstraintLayouts para aplanar la mayor parte de la jerarquía (como nunca antes !), entonces no creo que un poco de anidación hasta que esto esté mejor apoyado sea tan malo.
Entonces, lo que hice básicamente fue usar un FrameLayout, que está optimizado (o pensado) para tener un hijo (aunque puede contener más). Este FrameLayout es el que tiene las reglas ConstraintLayout aplicadas así:
<FrameLayout
android:id="@+id/hostTextWithCaretContainer"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent">
<!-- MY CONTENT GOES HERE -->
</FrameLayout>
Así que en mi aplicación real , este FrameLayout está dentro de otro ConstraintLayout que tiene un ícono a su izquierda y algunas otras cosas, pero por el bien de este ejemplo, imagina que tienes que "fijar" la izquierda / derecha de este FrameLayout a cualquier espacio quiero ocupar En este ejemplo, puedes ver que estoy usando parent
en todas las restricciones, pero podría haber otros widgets a la izquierda y derecha de este FrameLayout; Gracias a la magia de ConstraintLayout, esto ocupará todo el espacio disponible.
Ahora viene la segunda parte del truco ... ya que ConstraintLayout garantiza que FrameLayout usará "todo el espacio" que tenemos y nunca más (o menos), ahora puedo usar un LinearLayout en el interior ... así ...
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/textView"
android:layout_height="wrap_content"
android:layout_width="0dp"
tools:text="Some Text"
android:text="Some Text"
android:textAlignment="viewStart"
android:layout_gravity="center_vertical"
android:gravity="start"
android:ellipsize="end"
android:maxLines="1"
android:layout_weight="1"/>
<ImageView
android:id="@+id/caret"
android:layout_width="8dp"
android:layout_height="8dp"
app:srcCompat="@drawable/ic_selection"
android:contentDescription=""
android:layout_gravity="center_vertical"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp" />
</LinearLayout>
Los lectores astutos notarán que el LinearLayout tiene wrap_content
en su ancho, eso es muy importante porque el TextView hijo puede tener un ancho de 0dp y un weight
de 1, lo que significa que tomará todo el espacio libre disponible después de que todos los otros widgets hayan calculado su ancho. .
En este caso particular, el caret
del otro niño (ImageView) no tiene peso especificado y tiene un ancho fijo, por lo tanto, TextView no tiene que compartir / dividir el espacio libre con nadie más y puede tomarlo todo (pero solo el espacio libre, recuerde) su ancho es 0dp).
Este enfoque menos eficiente , efectivamente logra exactamente lo que quería, aunque con menos Restricción y Magia de Disparo si así lo desea.
En el lado positivo, no tuve que crear una vista personalizada, realizar requestLayout()
matemáticas y emitir un requestLayout()
después de haber completado todas mis cuentas; este enfoque menos eficiente será / debería escalar y hasta que ConstraintLayout ofrezca una alternativa válida, puede ser suficiente como es.
Diríjase a los ingenieros de Google que respondieron en las redes sociales y finalmente se tomaron el tiempo para pensar en esto. Tal vez en el futuro, cuando estén escribiendo tareas y puntos de historia sobre ConstraintLayout 1.1, lo recuerden y encuentren una buena solución.
En mi caso, la actualización de julio de 2018 de Martin no funcionará:
Si está utilizando ConstraintLayout 1.1.0, la propiedad correcta a usar es
app:layout_constrainedWidth="true"
en lugar de laapp:layout_constraintWidth_default="wrap"
antiguaapp:layout_constraintWidth_default="wrap"
(y la contraparte de altura)
Tengo que usar android:width="wrap_content"
para la vista de texto con la app:layout_constrainedWidth="true"
. android:layout_width="0dp"
(match_constraint) hace que la vista de texto se estire para cadenas más cortas en mi caso.
Otra posibilidad para lograr el mismo resultado sería usar android:layout_width="0dp"
con la app:layout_constraintWidth_max="wrap"
flag app:layout_constraintWidth_max="wrap"
lugar.
Puede encontrar más información sobre las banderas para el diseño de restricciones en doc: https://developer.android.com/reference/android/support/constraint/ConstraintLayout
En realidad, aquí es cómo podría hacerlo para TextViews: use android:maxWidth
:
<TextView
android:id="@+id/textView7"
android:maxWidth="200dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:ellipsize="end"
android:text="TextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextView"
tools:layout_editor_absoluteY="72dp"
android:layout_marginStart="16dp"
app:layout_constraintLeft_toLeftOf="parent"
android:layout_marginLeft="16dp" />
<Button
android:id="@+id/button20"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
tools:layout_editor_absoluteY="56dp"
android:layout_marginStart="8dp"
app:layout_constraintLeft_toRightOf="@+id/textView7"
android:layout_marginLeft="8dp" />
No es exactamente lo que pidió (necesita saber y establecer el tamaño para limitar el ancho), pero eso podría ayudarlo hasta que lo admitamos en ConstraintLayout.
Puede usar el diseño relativo en el diseño de restricción con margen negativo para ImageView. Por favor, atención a android:layout_marginRight="26dp"
y android:layout_marginLeft="-26dp"
<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"
android:orientation="vertical">
<RelativeLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="8dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_gravity="center_vertical"
android:layout_marginRight="26dp"
android:ellipsize="end"
android:gravity="start"
android:maxLines="1"
android:text="Some text" />
<ImageView
android:id="@+id/imageView"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_centerVertical="true"
android:layout_marginLeft="-26dp"
android:layout_toRightOf="@+id/textView"
android:contentDescription=""
android:src="@drawable/ic_browser" />
</RelativeLayout>
</android.support.constraint.ConstraintLayout>