Autorisierende Methode zum Überschreiben von onMeasure ()?
Lesezeit: 5 Minuten
U Avalos
Was ist der richtige Weg, um onMeasure() zu überschreiben? Ich habe verschiedene Ansätze gesehen. Zum Beispiel, Professionelle Android-Entwicklung verwendet MeasureSpec, um die Abmessungen zu berechnen, und endet dann mit einem Aufruf von setMeasuredDimension(). Zum Beispiel:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
this.setMeasuredDimension(parentWidth/2, parentHeight);
}
Auf der anderen Seite ist gemäß diesem Beitrag der “richtige” Weg, MeasureSpec zu verwenden, setMeasuredDimensions() aufzurufen, gefolgt von ein Aufruf von setLayoutParams() und endet mit einem Aufruf von super.onMeasure(). Zum Beispiel:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
this.setMeasuredDimension(parentWidth/2, parentHeight);
this.setLayoutParams(new *ParentLayoutType*.LayoutParams(parentWidth/2,parentHeight));
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
Was ist also der richtige Weg? Kein Ansatz hat bei mir zu 100% funktioniert.
Ich denke wirklich, was ich frage, ist, kennt jemand ein Tutorial, das onMeasure (), Layout, Abmessungen von untergeordneten Ansichten usw. erklärt?
Fanden Sie die Antwort hilfreich/richtig? warum nicht als markieren das Antworten?
– superjos
1. Dezember 2011 um 18:38 Uhr
Grimasse
Die anderen Lösungen sind nicht umfassend. Sie können in einigen Fällen funktionieren und sind ein guter Ausgangspunkt, aber es kann nicht garantiert werden, dass sie funktionieren.
Wenn onMeasure aufgerufen wird, haben Sie möglicherweise die Rechte, die Größe zu ändern. Die Werte, die an Ihr onMeasure (widthMeasureSpec, heightMeasureSpec) enthalten Informationen darüber, was Ihre untergeordnete Ansicht tun darf. Derzeit gibt es drei Werte:
MeasureSpec.UNSPECIFIED – Sie können so groß sein, wie Sie möchten
MeasureSpec.AT_MOST – So groß wie Sie wollen (bis zur angegebenen Größe), das ist parentWidth in deinem beispiel.
MeasureSpec.EXACTLY – Keine Wahl. Eltern haben gewählt.
Dies geschieht, damit Android mehrere Durchgänge durchführen kann, um die richtige Größe für jeden Artikel zu finden, siehe hier für mehr Details.
Wenn Sie diese Regeln nicht befolgen, funktioniert Ihr Ansatz garantiert nicht.
Wenn Sie beispielsweise überprüfen möchten, ob Sie die Größe überhaupt ändern dürfen, können Sie Folgendes tun:
final int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
final int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
boolean resizeWidth = widthSpecMode != MeasureSpec.EXACTLY;
boolean resizeHeight = heightSpecMode != MeasureSpec.EXACTLY;
Anhand dieser Informationen wissen Sie, ob Sie die Werte wie in Ihrem Code ändern können. Oder wenn Sie etwas anderes tun müssen. Eine schnelle und einfache Möglichkeit, Ihre gewünschte Größe zu ermitteln, ist die Verwendung einer der folgenden Methoden:
Während die erste nur auf Honeycomb verfügbar ist, ist die zweite auf allen Versionen verfügbar.
Hinweis: Sie können das finden resizeWidth oder resizeHeight sind immer falsch. Ich habe festgestellt, dass dies der Fall ist, wenn ich darum gebeten habe MATCH_PARENT. Ich konnte dies durch Anfrage beheben WRAP_CONTENT auf meinem übergeordneten Layout und dann während der UNSPECIFIED-Phase, in der eine Größe von angefordert wird Integer.MAX_VALUE. Dadurch erhalten Sie die maximale Größe, die Ihr Elternteil beim nächsten Durchgang durch onMeasure zulässt.
Zusammenfassend: am Ende Ihrer überschriebenen onMeasure Methode, die Sie aufrufen sollten setMeasuredDimension.
Sie sollten nicht anrufen super.onMeasure nach Anruf setMeasuredDimension, das löscht einfach alles, was Sie eingestellt haben. In manchen Situationen möchten Sie vielleicht anrufen super.onMeasure zuerst und ändern Sie dann die Ergebnisse durch Aufrufen setMeasuredDimension.
Rufen Sie nicht an setLayoutParams in onMeasure. Das Layout erfolgt in einem zweiten Durchgang nach dem Messen.
Meine Erfahrung ist, dass, wenn ich onMeasure überschreibe, ohne super.onMeasure aufzurufen, OnLayout nicht für untergeordnete Ansichten aufgerufen wird.
– Wilhelm Jockusch
11. Juni 2014 um 1:24 Uhr
YON
Ich denke, es hängt von dem übergeordneten Element ab, das Sie außer Kraft setzen.
Wenn Sie beispielsweise eine ViewGroup (wie FrameLayout) erweitern und die Größe gemessen haben, sollten Sie wie unten aufrufen
weil Sie vielleicht möchten, dass ViewGroup Restarbeiten erledigt (einige Dinge in der untergeordneten Ansicht erledigen)
Wenn Sie eine Ansicht (wie ImageView) erweitern, können Sie einfach aufrufen this.setMeasuredDimension(width, height);weil die übergeordnete Klasse einfach etwas tun wird, was Sie normalerweise getan haben.
Kurz gesagt, wenn Sie einige Funktionen wünschen, die Ihre Elternklasse kostenlos anbietet, sollten Sie anrufen super.onMeasure() (MeasureSpec.EXACTLY Mode Measure Spec wird normalerweise übergeben), andernfalls aufrufen this.setMeasuredDimension(width, height); reicht.
Wenn Sie die Ansichtsgröße innerhalb von ändern onMeasure Alles, was Sie brauchen, ist die setMeasuredDimension Anruf. Wenn Sie die Größe außerhalb ändern onMeasure du musst anrufen setLayoutParams. Ändern Sie beispielsweise die Größe einer Textansicht, wenn der Text geändert wird.
Hängt von der verwendeten Steuerung ab. Die Anweisungen in der Dokumentation funktionieren für einige Steuerelemente (TextView, Button, …), aber nicht für andere (LinearLayout, …). Der Weg, der für mich sehr gut funktionierte, war, den Supervisor anzurufen, wenn ich fertig bin. Basierend auf dem Artikel im folgenden Link.
Außerdem war es für die ViewPager-Komponente notwendig
M. Schenk
Ich denke, setLayoutParams und die Neuberechnung der Maße ist eine Problemumgehung, um die Größe der untergeordneten Ansichten korrekt zu ändern, da dies normalerweise in onMeasure der abgeleiteten Klasse erfolgt.
Dies funktioniert jedoch selten korrekt (aus welchen Gründen auch immer …), rufen Sie besser measureChildren auf (beim Ableiten einer ViewGroup) oder versuchen Sie bei Bedarf etwas Ähnliches.
12990600cookie-checkAutorisierende Methode zum Überschreiben von onMeasure ()?yes
Fanden Sie die Antwort hilfreich/richtig? warum nicht als markieren das Antworten?
– superjos
1. Dezember 2011 um 18:38 Uhr