Sobes.tech
Junior

Está familiarizado com o ciclo de vida da View no Android?

sobes.tech IA

Resposta da IA

Sim, conheço.

O ciclo de vida de uma View consiste em várias etapas-chave:

  1. Medida (Measurement): Determina o tamanho da View e das suas Views filhas. Acontece em duas passagens:
    • measure(int widthMeasureSpec, int heightMeasureSpec): Executa a medição.
    • onMeasure(int widthMeasureSpec, int heightMeasureSpec): Sobrescrito para implementar a lógica de medição.
  2. Disposição (Layout): Define a posição da View e das suas Views filhas. Acontece numa única passagem:
    • layout(int l, int t, int r, int b): Define a posição.
    • onLayout(boolean changed, int l, int t, int r, int b): Sobrescrito para implementar a lógica de disposição.
  3. Desenho (Drawing): Desenha a View e as suas Views filhas num Canvas. Acontece numa única passagem:
    • draw(Canvas canvas): Executa o desenho.
    • onDraw(Canvas canvas): Sobrescrito para implementar a lógica de desenho.
  4. Anexar/Desanexar (Attach/Detach): Indica se a View está anexada à janela ou desligada dela.
    • onAttachedToWindow(): É chamado ao anexar.
    • onDetachedFromWindow(): É chamado ao desligar.

Durante o ciclo de vida, podem ocorrer pedidos de re-medida (requestLayout()) ou de re-desenho (invalidate()), levando à repetição das etapas correspondentes.

Para Views personalizadas, geralmente sobrescrevem-se os métodos onMeasure, onLayout e onDraw.

Tabela de métodos-chave:

Etapa Método de medição Método de disposição Método de desenho Método de anexar/desanexar
Processo measure() layout() draw()
Sobrescrita onMeasure() onLayout() onDraw() onAttachedToWindow(), onDetachedFromWindow()

Exemplo de sobrescrita de onMeasure numa View personalizada:

 // Na View personalizada
 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
     // Obter modo e tamanho de medição
     int widthMode = MeasureSpec.getMode(widthMeasureSpec);
     int widthSize = MeasureSpec.getSize(widthMeasureSpec);
     int heightMode = MeasureSpec.getMode(heightMeasureSpec);
     int heightSize = MeasureSpec.getSize(heightMeasureSpec);

     int desiredWidth = 100; // Largura desejada
     int desiredHeight = 100; // Altura desejada

     int width;
     int height;

     // Lidar com diferentes modos de medição
     if (widthMode == MeasureSpec.EXACTLY) {
         width = widthSize;
     } else if (widthMode == MeasureSpec.AT_MOST) {
         width = Math.min(desiredWidth, widthSize);
     } else { // MeasureSpec.UNSPECIFIED
         width = desiredWidth;
     }

     if (heightMode == MeasureSpec.EXACTLY) {
         height = heightSize;
     } else if (heightMode == MeasureSpec.AT_MOST) {
         height = Math.min(desiredHeight, heightSize);
     } else { // MeasureSpec.UNSPECIFIED
         height = desiredHeight;
     }

     // Definir dimensões finais da View
     setMeasuredDimension(width, height);
 }