Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


Manipulación de pesos en onMeasue para vistas personalizadas

Tengo una vista personalizada que estoy creando que escalará el tamaño de fuente de su hijo TextViews para caber todo en un conjunto de ancho, por lo que cada uno está en su propia línea. Obviamente, va a necesitar el ancho para averiguarlo. Había onMeasure() así:

 @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int widthSize = MeasureSpec.getSize(widthMeasureSpec); int lineWidth = widthSize - getPaddingLeft() - getPaddingRight(); // Change the text size until the largest line of text fits. while (lineWidth < calculateTextWidth()) { for (TextView textView : this.childViews) { float newSize = textView.getTextSize() - 1; textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, newSize); } } super.onMeasure(widthMeasureSpec, heightMeasureSpec); } 

calculateTextWidth() calcula el ancho de la mayor línea de texto, y todo funciona con eso. Este código funciona bien para los anchos de FILL_PARENT y WRAP_CONTENT, pero se atasca cuando intento darle un peso al componente y dejarlo auto-establecer su peso de esa manera – MeasureSpec.getSize(widthMeasureSpec) devuelve 0, como lo hace getMinimumSuggestedWidth() . Esto da un maravilloso error de actividad que no responde, ya que lineWidth siempre será menor que calculateTextWidth() volvería siempre, por lo while ciclo while se ejecuta para siempre. El código XML que usé fue esto, esencialmente:

 <com.my.widgets.ScalingTextViewGroup android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:orientation="vertical" android:gravity="center_horizontal" > <TextView android:id="@+id/text_1" android:text="Text 1" android:textSize="20sp" /> <TextView android:id="@+id/text_2" android:text="Text 2" android:textSize="18sp" /> <TextView android:id="@+id/text_3" android:text="Text 3" android:textSize="18sp" /> <TextView android:id="@+id/text_4" android:text="Text 4" android:textSize="18sp" /> </com.my.widgets.ScalingTextViewGroup> 

Entiendo por qué está regresando 0 – obviamente, se está estableciendo en 0 – pero ¿cómo puedo conseguir que use el layout_weight? Siento que es algo que debe tener una respuesta simple, pero estoy en una pérdida en cuanto a lo que es.

One Solution collect form web for “Manipulación de pesos en onMeasue para vistas personalizadas”

Terminé averiguándolo a través de un importante Google. En esta página me enteré de que onMeasure es realmente llamado dos veces cuando android:layout_weight se establece. Más tarde me enteré de que se menciona en cómo Android Dibuja Vistas que measure() se puede llamar cualquier número de veces, simplemente no sentarse inmediatamente en mi cerebro. El primer pase obviamente no puede dar un valor para el tamaño de cada niño, ya que no sabe cuáles son los pesos de todos los hermanos de View. Pasa a través de él una vez y da una anchura de 0 con un MeasureSpec.UNSPECIFIED para ver si el niño tiene restricciones específicas, entonces pasa otra vez para asignar los pesos reales con un MeasureSpec.EXACTLY. Mi actividad se estaba estropeando en el primer pase, por lo que nunca llegó a la etapa de diseño. Modificar mi onMeasure () con el siguiente código solucionó el problema.

 @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int widthMode = MeasureSpec.getMode(widthMeasureSpec); if (widthMode != MeasureSpec.UNSPECIFIED) { int widthSize = MeasureSpec.getSize(widthMeasureSpec); int lineWidth = widthSize - getPaddingLeft() - getPaddingRight(); // Change the text size until the largest line of text fits. while (lineWidth < calculateTextWidth()) { for (TextView textView : this.childViews) { float newSize = textView.getTextSize() - 1; textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, newSize); } } } super.onMeasure(widthMeasureSpec, heightMeasureSpec); } 
FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.