Wie kann ich die Größe einer Ansicht basierend auf der Größe des übergeordneten Layouts anpassen? Zum Beispiel habe ich eine RelativeLayout
, die den gesamten Bildschirm ausfüllt, und ich möchte, dass eine untergeordnete Ansicht, z. B. eine ImageView
, die gesamte Höhe und die Hälfte der Breite einnimmt?
Ich habe überschreiben alle anprobiert onMeasure
, onLayout
, onSizeChanged
, etc. und ich konnte es nicht an die Arbeit ....
Antworten:
Ich weiß nicht, ob noch jemand diesen Thread liest oder nicht, aber Jeffs Lösung bringt Sie nur auf halbem Weg dorthin (irgendwie wörtlich). Mit seiner onMeasure wird die Hälfte des Bildes in der Hälfte des übergeordneten Elements angezeigt. Das Problem ist, dass beim Aufrufen von super.onMeasure vor dem das Ändern
setMeasuredDimension
aller untergeordneten Elemente in der Ansicht anhand der Originalgröße erfolgt und die Ansicht dann nur halbiert wird, wenn diesetMeasuredDimension
Größe geändert wird.Stattdessen müssen Sie anrufen
setMeasuredDimension
(wie für eine OnMeasure-Überschreibung erforderlich) und eine neueLayoutParams
für Ihre Ansicht bereitstellen und dann anrufensuper.onMeasure
. Denken Sie daran, dass SieLayoutParams
vom übergeordneten Typ Ihrer Ansicht abgeleitet sind, nicht vom Typ Ihrer Ansicht.Ich glaube, das einzige Mal, wenn Sie Probleme mit dem Elternteil haben,
LayoutParams
ist, wenn das Elternteil ein istAbsoluteLayout
(was veraltet, aber manchmal immer noch nützlich ist).quelle
MeasureSpec.getSize(widthMeasureSpec)
wirklich die richtige Elternbreite an? Für mich gibt es nur zufällige Breiten zurück, die ziemlich nahe an der tatsächlichen Breite liegen, aber nicht genau sind.wrap_content
nicht der Fall ist. Die Antwort von Vic funktioniert in diesem Szenario nicht, der Kommentar von @ M.Schenk jedoch. Es spart auch einen zusätzlichen Layout-Pass. Sie sollten es auch als Antwort für die Sichtbarkeit veröffentlichen.super.onMeasure()
einfach die Auswirkungen des früheren Aufrufs an überschreiben und aufhebenthis.setMeasuredDimension()
?super.onMeasure()
die früheren Berechnungen nicht überschreibt.Sie können dieses Problem lösen, indem Sie eine benutzerdefinierte Ansicht erstellen und die onMeasure () -Methode überschreiben. Wenn Sie in Ihrer XML-Datei immer "fill_parent" für die layout_width verwenden, sollte der Parameter widthMeasureSpec, der an die onMeasusre () -Methode übergeben wird, die Breite des übergeordneten Elements enthalten.
Ihr XML würde ungefähr so aussehen:
quelle
Ich habe festgestellt, dass es am besten ist, die gemessenen Abmessungen nicht selbst einzustellen. Es gibt tatsächlich einige Verhandlungen zwischen der übergeordneten und der untergeordneten Ansicht, und Sie möchten den gesamten Code nicht neu schreiben .
Sie können jedoch die MeasureSpecs ändern und dann mit ihnen Super aufrufen. Ihre Ansicht wird nie erfahren, dass sie eine geänderte Nachricht von ihrem Elternteil erhält, und sich um alles für Sie kümmern:
quelle
Wenn Sie ein Layout und eine Ansicht in XML definieren, können Sie die Layoutbreite und -höhe einer Ansicht angeben, die entweder als Wrap-Inhalt oder als übergeordnetes Element gefüllt werden soll. Die Hälfte der Fläche einzunehmen ist etwas schwieriger, aber wenn Sie etwas hatten, das Sie auf der anderen Hälfte wollten, könnten Sie etwas wie das Folgende tun.
Wenn zwei Dinge das gleiche Gewicht haben, werden sie gedehnt, um den gleichen Anteil des Bildschirms einzunehmen. Weitere Informationen zu Layouts finden Sie in den Entwicklungsdokumenten.
quelle
Ich glaube, dass Mayras XML-Ansatz ordentlich kommen kann. Es ist jedoch möglich, die Genauigkeit mit nur einer Ansicht zu erhöhen, indem Sie die weightSum einstellen. Ich würde das nicht mehr als Hack bezeichnen, aber meiner Meinung nach der einfachste Ansatz:
So können Sie jedes Gewicht verwenden, zum Beispiel 0,6 (und Zentrierung) ist das Gewicht, das ich gerne für Schaltflächen verwende.
quelle
Versuche dies
Dann können Sie LinearLayout.LayoutParams verwenden, um die Parameter von chileView festzulegen
quelle
Sie können jetzt PercentRelativeLayout verwenden. Boom! Problem gelöst.
quelle
Roman, wenn Sie Ihr Layout in Java-Code (ViewGroup-Nachkomme) erstellen möchten, ist dies möglich. Der Trick besteht darin, dass Sie sowohl die onMeasure- als auch die onLayout-Methode implementieren müssen. Das onMeasure wird zuerst aufgerufen und Sie müssen die Unteransicht dort "messen" (effektiv auf den gewünschten Wert zuschneiden). Sie müssen die Größe im Aufruf von onLayout erneut anpassen. Wenn Sie diese Sequenz nicht ausführen oder setMeasuredDimension () am Ende Ihres onMeasure-Codes nicht aufrufen, erhalten Sie keine Ergebnisse. Warum dies so kompliziert und fragil gestaltet ist, ist mir ein Rätsel.
quelle
Wenn die andere Seite leer ist. Ich denke, der einfachste Weg wäre, eine leere Ansicht (z. B. ein lineares Layout) hinzuzufügen und dann die Breite beider Ansichten auf fill_parent und beide Gewichte auf 1 zu setzen.
Dies funktioniert in einem LinearLayout ...
quelle
Es ist ungefähr so:
quelle
Ich habe lange mit dieser Frage zu kämpfen. Ich möchte die Schubladenbreite meines DrawerLayout ändern, das das zweite Kind seines Elternteils ist. Kürzlich habe ich es herausgefunden, weiß aber nicht, ob es eine bessere Idee gibt.
quelle