onMeasure()
é a sua oportunidade de informar ao Android qual o tamanho que você deseja que sua visualização personalizada dependa das restrições de layout fornecidas pelos pais; também é a oportunidade da sua exibição personalizada para saber quais são essas restrições de layout (caso você queira se comportar de maneira diferente em uma match_parent
situação e em uma wrap_content
situação). Essas restrições são agrupadas nos MeasureSpec
valores que são passados para o método. Aqui está uma correlação aproximada dos valores de modo:
- EXATAMENTE significa que o valor
layout_width
ou layout_height
foi definido para um valor específico. Você provavelmente deve ter sua visualização desse tamanho. Isso também pode ser acionado quando match_parent
usado, para definir o tamanho exatamente para a visualização pai (isso depende do layout na estrutura).
- AT_MOST normalmente significa que o valor
layout_width
ou layout_height
foi definido como match_parent
ou wrap_content
onde é necessário um tamanho máximo (isso depende do layout na estrutura), e o tamanho da dimensão pai é o valor. Você não deve ser maior que esse tamanho.
- NÃO ESPECIFICADO normalmente significa que o valor
layout_width
ou layout_height
foi definido como wrap_content
sem restrições. Você pode ter o tamanho que desejar. Alguns layouts também usam esse retorno de chamada para descobrir o tamanho desejado antes de determinar quais especificações realmente serão enviadas novamente em uma segunda solicitação de medida.
O contrato que existe onMeasure()
é que setMeasuredDimension()
DEVE ser chamado no final com o tamanho que você deseja que a vista seja. Esse método é chamado por todas as implementações da estrutura, incluindo a implementação padrão encontrada em View
, e é por isso que é seguro chamar, super
se isso se encaixa no seu caso de uso.
Concedido, porque a estrutura aplica uma implementação padrão, pode não ser necessário substituir esse método, mas você pode ver recortes nos casos em que o espaço de exibição é menor que o seu conteúdo, se não o fizer, e se você definir o seu Na visualização personalizada, wrap_content
nas duas direções, a visualização pode não aparecer, porque a estrutura não sabe o tamanho dela!
Geralmente, se você está substituindo View
e não outro widget existente, provavelmente é uma boa idéia fornecer uma implementação, mesmo que seja tão simples quanto algo como isto:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int desiredWidth = 100;
int desiredHeight = 100;
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int width;
int height;
//Measure Width
if (widthMode == MeasureSpec.EXACTLY) {
//Must be this size
width = widthSize;
} else if (widthMode == MeasureSpec.AT_MOST) {
//Can't be bigger than...
width = Math.min(desiredWidth, widthSize);
} else {
//Be whatever you want
width = desiredWidth;
}
//Measure Height
if (heightMode == MeasureSpec.EXACTLY) {
//Must be this size
height = heightSize;
} else if (heightMode == MeasureSpec.AT_MOST) {
//Can't be bigger than...
height = Math.min(desiredHeight, heightSize);
} else {
//Be whatever you want
height = desiredHeight;
}
//MUST CALL THIS
setMeasuredDimension(width, height);
}
Espero que ajude.