onMeasure()
to okazja, by powiedzieć Androidowi, jak duży ma być twój niestandardowy widok od ograniczeń układu dostarczonych przez rodzica; jest to również okazja, aby w widoku niestandardowym dowiedzieć się, jakie są ograniczenia układu (w przypadku, gdy chcesz zachowywać się inaczej w match_parent
sytuacji niż w wrap_content
sytuacji). Ograniczenia te są pakowane w MeasureSpec
wartości przekazywane do metody. Oto przybliżona korelacja wartości trybu:
- DOKŁADNIE oznacza, że wartość
layout_width
lub layout_height
została ustawiona na określoną wartość. Prawdopodobnie powinieneś zrobić widok tego rozmiaru. Można to również uruchomić, gdy match_parent
jest używane, aby ustawić rozmiar dokładnie w widoku nadrzędnym (jest to zależne od układu w ramach).
- AT_MOST zazwyczaj oznacza, że wartość
layout_width
lub layout_height
została ustawiona na match_parent
lub wrap_content
tam, gdzie potrzebny jest maksymalny rozmiar (jest to zależne od układu w strukturze), a rozmiar wymiaru nadrzędnego jest wartością. Nie powinieneś być większy niż ten rozmiar.
- NIEPECYFIKOWANE zazwyczaj oznacza, że wartość
layout_width
lub layout_height
została ustawiona wrap_content
bez żadnych ograniczeń. Możesz mieć dowolną wielkość. Niektóre układy również używają tego wywołania zwrotnego, aby ustalić pożądany rozmiar przed określeniem, jakie specyfikacje faktycznie przekazać ponownie w żądaniu drugiego pomiaru.
Umowa, która istnieje onMeasure()
, setMeasuredDimension()
MUSI być wywoływana na końcu z rozmiarem, jaki chcesz mieć widok. Ta metoda jest wywoływana przez wszystkie implementacje frameworka, w tym implementację domyślną znalezioną w View
, dlatego można bezpiecznie wywoływać super
zamiast tego, jeśli pasuje to do twojego przypadku użycia.
To prawda, że ponieważ struktura ma domyślną implementację, może nie być konieczne zastąpienie tej metody, ale możesz zobaczyć obcinanie w przypadkach, gdy przestrzeń widoku jest mniejsza niż treść, jeśli nie, i jeśli rozłożysz widok niestandardowy wrap_content
w obu kierunkach może wcale nie być wyświetlany, ponieważ struktura nie wie, jak duży jest!
Ogólnie rzecz biorąc, jeśli przesłonisz, View
a nie inny istniejący widget, prawdopodobnie dobrym pomysłem jest zapewnienie implementacji, nawet jeśli jest tak prosta jak coś takiego:
@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);
}
Mam nadzieję, że to pomaga.