vistas studio sirve que propiedades para libreria grupos example clase addview java android android-activity view onmeasure

java - studio - ¿Cuándo se llama View.onMeasure()?



propiedades de la clase view android (2)

Puede obtener las medidas de su vista personalizada en onSizeChanged .

@Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); // use the provided width and height for whatever you need }

Explicación

Cuando se crea una vista, este es el orden en que se llaman los siguientes métodos:

  1. Constructor
    • CustomView(Context context) (si se crea mediante programación)
    • CustomView(Context context, AttributeSet attrs) (si se crea a partir de xml)
  2. onFinishInflate (asumiendo que onFinishInflate el constructor xml)
  3. onAttachedToWindow
  4. onMeasure
  5. onSizeChanged
  6. onLayout
  7. onDraw

Lo más temprano que puede obtener las mediciones de la vista es en onMeasure . Antes de eso el ancho y la altura son 0 . Sin embargo, lo único que debe hacer en onMeasure es determinar el tamaño de la vista. Este método se llama varias veces mientras la vista le dice al padre qué tan grande quiere ser, pero el padre está determinando el tamaño final real. (Consulte esta respuesta para onMeasure cómo se debe utilizar onMeasure ).

Si realmente desea utilizar el tamaño medido para cualquier cosa, el primer lugar para hacerlo es en el onSizeChanged de onSizeChanged . Se llama cuando se crea la vista porque el tamaño cambia de 0 a cualquiera que sea el tamaño.

También puede utilizar onLayout , aunque, según tengo entendido, onLayout es para personalizar cómo se onLayout de su vista personalizada. También puede recibir llamadas con mayor frecuencia que onSizeChanged , por ejemplo, si llama a requestLayout() cuando el tamaño no ha cambiado realmente.

También puede acceder al tamaño en onDraw con getMeasuredWidth() y getMeasuredHeight() . Sin embargo, si los está utilizando para realizar cálculos pesados, es mejor hacerlo de antemano. En términos generales, trate de mantener lo más alejado posible de onDraw ya que puede llamarse varias veces. (Se llama cuando se invalidate() ).

Ver por ti mismo

Si no me cree, puede ver el orden de los eventos tal como se denominan en la vista personalizada a continuación. Aquí está la salida:

XML constructor called, measured size: (0, 0) onFinishInflate called, measured size: (0, 0) onAttachedToWindow called, measured size: (0, 0) onMeasure called, measured size: (350, 1859) onMeasure called, measured size: (350, 350) onMeasure called, measured size: (350, 2112) onMeasure called, measured size: (350, 350) onSizeChanged called, measured size: (350, 350) onLayout called, measured size: (350, 350) onDraw called, measured size: (350, 350)

activity_main.xml

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent"> <com.example.viewlifecycle.CustomView android:id="@+id/customView" android:layout_width="100dp" android:layout_height="100dp" android:background="@color/colorAccent"/> </RelativeLayout>

CustomView.java

public class CustomView extends View { private void printLogInfo(String methodName) { Log.i("TAG", methodName + " called, measured size: (" + getMeasuredWidth() + ", " + getMeasuredHeight() + ")"); } // constructors public CustomView(Context context) { super(context); printLogInfo("Programmatic constructor"); } public CustomView(Context context, AttributeSet attrs) { super(context, attrs); printLogInfo("XML constructor"); } // lifecycle methods @Override protected void onFinishInflate() { super.onFinishInflate(); printLogInfo("onFinishInflate"); } @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); printLogInfo("onAttachedToWindow"); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); printLogInfo("onMeasure"); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); printLogInfo("onSizeChanged"); } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); printLogInfo("onLayout"); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); printLogInfo("onDraw"); } }

Otras lecturas

Cuando es

View.onMeasure(int widthMeasureSpec, int heightMeasureSpec)

¿llamado? Tengo una Activity que necesita realizar una acción después de que se haya llamado onMeasure .

Mi pregunta es la misma que la pregunta sin respuesta publicada aquí . La documentación de la View indica que se llama a requestLayout() cuando se llama a requestLayout() , que aparentemente la llama una vista en sí misma cuando cree que ya no puede encajar dentro de sus límites actuales.

Sin embargo, esto no me dice cuándo mi actividad puede suponer que mi View se ha medido. He usado este código para extender ImageView para formar TouchImageView. Se sugirió aquí que debería usar el método onMeasure para escalar mi imagen. Deseo actualizar el valor de un TextView después de que se haya medido ImageView para mostrar el porcentaje por el que se ha escalado la imagen.


Se llama a onMeasure cuando la Vista principal necesita calcular el diseño. Normalmente, se puede llamar a onMeasure varias veces dependiendo de los diferentes niños presentes y sus parámetros de diseño.

La mejor manera de hacer algo cuando se llama onMeasure es (creo) crear su propio control, extender ImageView y anular onMeasure (solo llame a super.onMeasure y haga lo que quiera).

Si lo hace, solo tenga en cuenta que en Measure puede llamarse varias veces con diferentes parámetros, por lo que lo que se mida puede no ser el ancho y la altura finales de lo que realmente se mostrará.