109 Stimmen

Wie man die Größe einer Android-Ansicht basierend auf den Abmessungen der übergeordneten Ansicht bestimmt

Wie kann ich die Größe einer Ansicht auf der Grundlage der Größe ihres übergeordneten Layouts bestimmen? Ich habe zum Beispiel eine RelativeLayout die den gesamten Bildschirm ausfüllt, und ich möchte eine untergeordnete Ansicht, beispielsweise eine ImageView die gesamte Höhe und die Hälfte der Breite einnehmen?

Ich habe versucht, alle auf onMeasure , onLayout , onSizeChanged usw. und ich konnte es nicht zum Laufen bringen....

0 Stimmen

Es ist möglich, das mit ConstraintLayout zu tun, überprüfen Sie dies: stackoverflow.com/questions/37318228/

124voto

Vic Punkte 5867

Ich weiß nicht, ob noch jemand diesen Thread liest oder nicht, aber Jeffs Lösung bringt Sie nur halbwegs ans Ziel (im wahrsten Sinne des Wortes). Was seine onMeasure tun wird, ist die Hälfte des Bildes in der Hälfte des Elternteils anzuzeigen. Das Problem ist, dass der Aufruf super.onMeasure vor dem setMeasuredDimension misst alle Kinder in der Ansicht auf der Grundlage der ursprünglichen Größe und halbiert dann die Ansicht, wenn die setMeasuredDimension ändert sie die Größe.

Stattdessen müssen Sie Folgendes aufrufen setMeasuredDimension (wie für eine onMeasure-Überschreibung erforderlich) und eine neue LayoutParams für Ihre Ansicht, dann aufrufen super.onMeasure . Denken Sie daran, dass Ihr LayoutParams werden von dem übergeordneten Typ Ihrer Ansicht abgeleitet, nicht von dem Typ Ihrer Ansicht.

@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);
}

Ich glaube, das einzige Mal, dass Sie Probleme mit den Eltern haben werden LayoutParams ist, wenn der Elternteil ein AbsoluteLayout (was veraltet, aber manchmal noch nützlich ist).

12 Stimmen

Meiner Erfahrung nach funktioniert das selten, vor allem wenn fill/match_parent oder weights aufgerufen werden. Rufen Sie measureChildren besser nach setMeasuredDimension auf (z. B. mit MeasureSpec.makeMeasureSpec(newWidth, MeasureSpec.AT_MOST)).

0 Stimmen

Ich muss den linken Rand eines TextViews ändern, anstatt seine Größe abhängig von der Breite des übergeordneten Layouts. Mit Ihrem Code funktioniert es mehr oder weniger, aber es gibt mir seltsame Ergebnisse, wenn Sie es in den Zeilen eines ListView, d. h. es ist nicht immer in der richtigen Position nach dem Scrollen. Muss ich eine andere Methode außer Kraft setzen? Wie sollte ich setMeasuredDimension in diesem Fall aufrufen?

1 Stimmen

Hat MeasureSpec.getSize(widthMeasureSpec) wirklich die richtige Breite der Eltern angeben? Für mich gibt es nur zufällige Breiten, die ziemlich nah an der tatsächlichen Breite sind, aber nicht genau.

43voto

Jeff Punkte 664

Sie können dieses Problem lösen, indem Sie eine benutzerdefinierte Ansicht erstellen und die onMeasure()-Methode außer Kraft setzen. Wenn Sie immer "fill_parent" für die layout_width in Ihrer xml verwenden, sollte der widthMeasureSpec-Parameter, der an die onMeasusre()-Methode übergeben wird, die Breite des Elternteils enthalten.

public class MyCustomView extends TextView {

    public MyCustomView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
        int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
        this.setMeasuredDimension(parentWidth / 2, parentHeight);
    }
}   

Ihr XML würde etwa so aussehen:

<LinearLayout 
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <view
        class="com.company.MyCustomView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

2 Stimmen

@jeff => warum parentWidth / 2 ?

6 Stimmen

@Leon_SFS: In der Frage wird danach gefragt: "ganze Höhe und 1/2 der Breite"

29voto

Phil Kulak Punkte 6292

Ich habe die Erfahrung gemacht, dass es am besten ist, die gemessenen Maße nicht selbst einzustellen. Es gibt tatsächlich ein bisschen Verhandlung, die zwischen der übergeordneten und der untergeordneten Ansicht stattfindet, und Sie wollen das nicht alles neu schreiben Code .

Was Sie jedoch tun können, ist die measureSpecs ändern, dann rufen Sie super mit ihnen. Ihre Ansicht wird nie wissen, dass sie eine geänderte Nachricht von ihrem Elternteil erhält und wird sich um alles für Sie kümmern:

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
    int myWidth = (int) (parentHeight * 0.5);
    super.onMeasure(MeasureSpec.makeMeasureSpec(myWidth, MeasureSpec.EXACTLY), heightMeasureSpec);
}

17voto

Cheryl Simon Punkte 45901

Wenn Sie ein Layout und eine Ansicht im XML-Format definieren, können Sie die Layoutbreite und -höhe einer Ansicht so festlegen, dass sie entweder wrap_content o fill_parent . Die Hälfte der Fläche einzunehmen ist etwas schwieriger, aber wenn man etwas auf der anderen Hälfte haben möchte, könnte man etwas wie das Folgende machen.

<LinearLayout android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <ImageView android:layout_height="fill_parent"
        android:layout_width="0dp"
        android:layout_weight="1" />
    <ImageView android:layout_height="fill_parent"
        android:layout_width="0dp"
        android:layout_weight="1" />
</LinearLayout>

Wenn zwei Dinge das gleiche Gewicht haben, nehmen sie den gleichen Teil des Bildschirms ein. Für weitere Informationen über Layouts siehe die Entwicklungsdokumente.

0 Stimmen

Ich empfehle dies nicht, aber... als Hack, wenn Sie den obigen Ansatz verwenden, könnten Sie eine dieser Ansichten zu einem "Dummy" machen und Android:visibility="invisible" setzen, um die Hälfte des Bereichs zu füllen

0 Stimmen

Welchen Sinn hat es, nur die Hälfte der Fläche zu nutzen? Wollen Sie auf der anderen Hälfte etwas ausstellen? Was Sie mit der verbleibenden Fläche machen, bestimmt den besten Ansatz

0 Stimmen

Dies sollte auf jeden Fall die Nummer 1 sein - wenn Sie es in Ihrem XML tun können, warum sollten Sie es in Ihrem Java tun?

9voto

pinkwerther Punkte 313

Ich glaube, dass Mayras XML-Ansatz können in ordentlicher Form kommen. Allerdings ist es möglich, es genauer zu machen, mit nur einer Ansicht durch die Einstellung der weightSum. Ich würde dies nicht mehr als Hack bezeichnen, sondern meiner Meinung nach als den einfachsten Ansatz:

<LinearLayout android:layout_width="fill_parent"
              android:layout_height="fill_parent"
              android:weightSum="1">
    <ImageView android:layout_height="fill_parent"
               android:layout_width="0dp"
               android:layout_weight="0.5"/>
</LinearLayout>

Auf diese Weise können Sie ein beliebiges Gewicht verwenden, 0,6 zum Beispiel (und Zentrierung) ist das Gewicht, das ich gerne für Schaltflächen verwende.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X