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_parentsytuacji niż w wrap_contentsytuacji). Ograniczenia te są pakowane w MeasureSpecwartości przekazywane do metody. Oto przybliżona korelacja wartości trybu:
- DOKŁADNIE oznacza, że wartość
layout_widthlub layout_heightzostała ustawiona na określoną wartość. Prawdopodobnie powinieneś zrobić widok tego rozmiaru. Można to również uruchomić, gdy match_parentjest 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_widthlub layout_heightzostała ustawiona na match_parentlub wrap_contenttam, 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_widthlub layout_heightzostała ustawiona wrap_contentbez ż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ć superzamiast 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_contentw 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, Viewa 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.