onMeasure()
ist Ihre Gelegenheit, Android mitzuteilen, wie groß Ihre benutzerdefinierte Ansicht von den vom Elternteil bereitgestellten Layoutbeschränkungen abhängen soll. Es ist auch die Gelegenheit Ihrer benutzerdefinierten Ansicht, die Layoutbeschränkungen zu erfahren (falls Sie sich in einer match_parent
Situation anders als in einer Situation verhalten möchten wrap_content
). Diese Einschränkungen werden in die MeasureSpec
Werte gepackt, die an die Methode übergeben werden. Hier ist eine grobe Korrelation der Moduswerte:
- GENAU bedeutet, dass der Wert
layout_width
oder layout_height
auf einen bestimmten Wert gesetzt wurde. Sie sollten Ihre Ansicht wahrscheinlich auf diese Größe einstellen. Dies kann auch ausgelöst werden, wenn match_parent
es verwendet wird, um die Größe genau auf die übergeordnete Ansicht einzustellen (dies ist im Framework vom Layout abhängig).
- AT_MOST bedeutet normalerweise, dass der Wert
layout_width
oder layout_height
auf festgelegt wurde match_parent
oder wrap_content
wo eine maximale Größe benötigt wird (dies ist vom Framework abhängig), und die Größe der übergeordneten Dimension ist der Wert. Sie sollten nicht größer als diese Größe sein.
- UNSPECIFIED bedeutet normalerweise, dass der Wert
layout_width
oder ohne Einschränkungen festgelegt wurde. Sie können jede Größe haben, die Sie möchten. Einige Layouts verwenden diesen Rückruf auch, um Ihre gewünschte Größe zu ermitteln, bevor Sie festlegen, welche Spezifikationen Sie in einer zweiten Kennzahlanforderung tatsächlich erneut übergeben sollen.layout_height
wrap_content
Der Vertrag, der mit onMeasure()
besteht, setMeasuredDimension()
muss am Ende mit der Größe aufgerufen werden, die die Ansicht haben soll. Diese Methode wird von allen Framework-Implementierungen aufgerufen, einschließlich der Standardimplementierung in View
. Daher ist es sicher, super
stattdessen aufzurufen, wenn dies Ihrem Anwendungsfall entspricht.
Zugegeben, da das Framework eine Standardimplementierung anwendet, müssen Sie diese Methode möglicherweise nicht überschreiben. In Fällen, in denen der Ansichtsbereich kleiner als Ihr Inhalt ist, wird möglicherweise ein Clipping angezeigt, wenn Sie dies nicht tun und wenn Sie Ihre festlegen Benutzerdefinierte Ansicht mit wrap_content
in beide Richtungen, Ihre Ansicht wird möglicherweise überhaupt nicht angezeigt, da das Framework nicht weiß, wie groß es ist!
Wenn Sie überschreiben View
und kein anderes vorhandenes Widget verwenden, ist es im Allgemeinen wahrscheinlich eine gute Idee, eine Implementierung bereitzustellen, auch wenn dies so einfach ist:
@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);
}
Ich hoffe, das hilft.