TextView funciona mal con breakStrategy = "equilibrado" y layout_width = "wrap_content"
Tengo tal disposición (he quitado algunos atributos, causa que realmente no importa, proyecto de demostración completo está aquí ):
<LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:layout_width="wrap_content" (* this is important) android:layout_height="wrap_content" android:breakStrategy="balanced" (* this is important) android:text="@string/long_text" /> </LinearLayout>
El texto long_text
es bastante largo, por lo que sería separado por unas pocas líneas.
- Cómo animar el textview (texto muy largo) desplazarse automáticamente horizontalmente
- Despliegue y alineación de la distribución relativa de Android
- ¿Dónde debo colocar los archivos "ttf" en un proyecto de Android?
- Android TextView: "No concatenar el texto mostrado con setText"
- Img src atributo de json valor que muestra pequeña caja de color azul en Android TextView
Dos líneas importantes son android:layout_width="wrap_content"
y android:breakStrategy="balanced"
.
Espero que TextView
calculará el ancho según el ancho real del texto , pero no lo hace.
Sabe alguien cómo arreglar esto?
ACTUALIZAR
Atributo android:breakStrategy="balanced"
sólo funciona para API 23
y superior. En mi ejemplo el texto toma 3 líneas, y balanced
estrategia balanced
hace que cada línea tenga aproximadamente el mismo ancho.
Espero que en este caso el ancho de vista en sí será el mismo que la línea más larga.
Estoy buscando cualquier solución. Necesito una solución como en el chat de Hangouts. No puedo entender cómo funciona.
ACTUALIZAR 2
Desafortunadamente, la respuesta aceptada no funciona con texto RTL.
- ¿Cómo puedo establecer el estilo de un textView programatically?
- El tamaño de fuente de TextView en la aplicación Android cambia al cambiar el tamaño de la fuente de la configuración nativa
- Sobreponiendo problema en Android TextView
- Establecer color de fondo en sólo (1/4) th parte de una vista (Android)
- Más espacio entre líneas en TextView
- Android TextView Scrollable
- Cómo hacer un fondo 20% transparente en Android
- Envoltura de texto uniforme en TextView
Esto sucede porque cuando TextView calcula su ancho, mide todo el texto como 1 línea (en su caso) y en este paso no sabe nada sobre android: breakStrategy. Por lo tanto, está tratando de utilizar todo el espacio disponible para renderizar tanto texto en primera línea como pueda.
Para obtener más detalles, por favor compruebe el método int desired(Layout layout)
aquí
Para solucionarlo puedes usar esta clase:
public class MyTextView extends TextView { public MyTextView(Context context) { super(context); } public MyTextView(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); Layout layout = getLayout(); if (layout != null) { int width = (int) Math.ceil(getMaxLineWidth(layout)) + getCompoundPaddingLeft() + getCompoundPaddingRight(); int height = getMeasuredHeight(); setMeasuredDimension(width, height); } } private float getMaxLineWidth(Layout layout) { float max_width = 0.0f; int lines = layout.getLineCount(); for (int i = 0; i < lines; i++) { if (layout.getLineWidth(i) > max_width) { max_width = layout.getLineWidth(i); } } return max_width; }
}
Que tomé aquí – ¿Por qué se envuelve el contenido en la línea múltiple TextView relleno padre?
Necesitará medir el ancho del texto en TextView
programática, así:
Rect bounds = new Rect(); textView.getPaint().getTextBounds(textView.getText().toString(), 0, textView.getText().length(), bounds);
Ahora, puede colocar un rectángulo de color detrás del TextView
y establecer su anchura programáticamente después de medir el texto (estoy usando FrameLayout
para poner las vistas una encima de la otra, pero también puede usar RelativeLayout
):
XML:
<FrameLayout android:layout_width="match_parent" android:layout_height="match_parent"> <View android:id="+@id/background" android:layout_width="0dp" android:layout_height="wrap_content" android:background="@color/green" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:breakStrategy="balanced" android:text="@string/long_text" /> </FrameLayout>
Código:
Rect bounds = new Rect(); textView.getPaint().getTextBounds(textView.getText().toString(), 0, textView.getText().length(), bounds); View bg = findViewById(R.id.background); gb.getLayoutParams().width = bounds.width();
El código no ha sido probado, pero estoy seguro de que obtienes el punto.
ACTUALIZAR
Puede ser posible hacer esto sin usar una segunda view
fondo, estableciendo el ancho de TextView
para que coincida con bounds.width()
, pero esto desencadena un cambio en cómo se rompe el texto, así que tenga cuidado de no causar un bucle infinito.
- Error al resolver: com.google.firebase: firebase-auth: 9.0.0
- ¿Cómo recuperar los informes de fallos de una aplicación portátil?