Was ist android: weightSum in android und wie funktioniert es?

Antworten:

132

Definiert gemäß Dokumentation android:weightSumdie maximale Gewichtssumme und wird als die Summe layout_weightaller untergeordneten Elemente berechnet, wenn nicht explizit angegeben.

Betrachten wir ein Beispiel mit einer LinearLayouthorizontalen Ausrichtung und 3 ImageViewsdarin. Jetzt wollen wir, dass diese ImageViewsimmer den gleichen Platz einnehmen. Um dies zu erreichen, können Sie layout_weightjeweils ImageView1 auf 1 setzen und das weightSumwird wie im Kommentar gezeigt gleich 3 berechnet.

<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    <!-- android:weightSum="3" -->
    android:orientation="horizontal"
    android:layout_gravity="center">

   <ImageView
       android:layout_height="wrap_content"       
       android:layout_weight="1"
       android:layout_width="0dp"/>
  .....

weightSum Dies ist nützlich, damit das Layout für jedes Gerät korrekt gerendert wird. Dies ist nicht der Fall, wenn Sie Breite und Höhe direkt einstellen.

superM
quelle
144
Dies ist keine Erklärung des Zwecks von weightSum. Das Verhalten in Ihrem Beispiel ist identisch mit weightSumweggelassen, und tatsächlich sollte weightSum in diesem Szenario nicht angegeben werden. Die Dokumentation sagt,weightSum Defines the maximum weight sum. If unspecified, the sum is computed by adding the layout_weight of all of the children.
Jeff Axelrod
3
@ JeffAxelrod: Es sollte nicht angegeben werden? Warum? Ich sehe keinen Grund dafür. Ich würde also nur sagen, dass es nicht spezifiziert werden muss.
Caw
17
@MarcoW.: Es sollte aus Gründen der Wartbarkeit nicht angegeben werden. Wie Jeff sagte, führt das Festlegen der weightSum auf die Summe der Gewichte innerhalb des Layouts zu nichts, aber wenn jemand es in Zukunft ändert, kann dies zu Kopfschmerzen führen, da jetzt ein unnötiger Modifikator für das Layout gefunden werden muss und geändert. Diese Antwort ist falsch und sollte nicht die akzeptierte Antwort sein.
d370urn3ur
3
Es gibt keine gute Erklärung für den weightSum-Parameter, daher aus den Dokumenten: "Dies kann beispielsweise verwendet werden, um einem einzelnen Kind 50% des gesamten verfügbaren Speicherplatzes zu geben, indem es ein layout_weight von 0,5 erhält und die weightSum auf 1,0 setzt." Siehe developer.android.com/reference/android/widget/…
Deepscorn
5
Die Idee ist, dass Sie weightSum auf eine Zahl setzen können, die höher ist als die Summe der Kinder. Dies führt dazu, dass die Kinder einen Teil, aber nicht den gesamten verfügbaren zusätzlichen Platz erhalten. Im obigen Beispiel würde Ihr einzelnes Kind die Hälfte des verfügbaren Speicherplatzes anstelle des gesamten erben.
Edward Falk
175

Hinzufügen zu der Antwort von superM und Jeff,

Wenn das LinearLayout zwei Ansichten enthält, die erste mit einem layout_weight von 1, die zweite mit einem layout_weight von 2 und ohne weightSum. Standardmäßig wird die weightSum mit 3 (Summe der Gewichte der untergeordneten Elemente) und berechnet Die erste Ansicht nimmt 1/3 des Platzes ein, während die zweite 2/3 einnimmt.

Wenn wir jedoch die weightSum als 5 angeben würden, würde die erste 1/5 des Leerzeichens einnehmen, während die zweite 2/5 einnehmen würde. Insgesamt würde also 3/5 des Platzes durch das Layout belegt, während der Rest leer bleibt.

Shubhayu
quelle
2
Ich habe nach dem gleichen gesucht, was passiert, wenn keine Gewichtssumme definiert ist und die untergeordneten Ansichten gewichtet werden. Ihre Antwort, dass es selbst berechnet, löschte alles
DeltaCap019
Stimmt es, dass empfohlen wird, RelativeLayout als Layouts mit weightSum zu verwenden?
Robert
26

Die Gewichtssumme funktioniert genau so, wie Sie möchten (wie bei anderen Antworten müssen Sie nicht alle Gewichte im übergeordneten Layout summieren). Geben Sie in der untergeordneten Ansicht das Gewicht an, das Sie annehmen möchten. Vergessen Sie nicht anzugeben

android:layout_width="0dp" 

Es folgt ein Beispiel

    <LinearLayout
                android:layout_width="500dp"
                android:layout_height="20dp" >

                <TextView
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="3"
                    android:background="@android:color/holo_green_light"
                    android:gravity="center"
                    android:text="30%"
                    android:textColor="@android:color/white" >
                </TextView>

                <TextView
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="2"
                    android:background="@android:color/holo_blue_bright"
                    android:gravity="center"
                    android:text="20%"
                    android:textColor="@android:color/white" >
                </TextView>

                <TextView
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="5"
                    android:background="@android:color/holo_orange_dark"
                    android:gravity="center"
                    android:text="50%"
                    android:textColor="@android:color/white" >
                </TextView>
 </LinearLayout>

Das wird so aussehen

Geben Sie hier die Bildbeschreibung ein

Asok Buzz
quelle
25

Die Dokumentation sagt es am besten und enthält ein Beispiel (das meine hervorhebt).

android: weightSum

Definiert die maximale Gewichtssumme. Wenn nicht angegeben, wird die Summe berechnet, indem das layout_weight aller untergeordneten Elemente hinzugefügt wird. Dies kann zum Beispiel verwendet werden, um einem einzelnen Kind 50% des gesamten verfügbaren Speicherplatzes zu geben, indem es ein layout_weight von 0,5 gibt und die weightSum auf 1,0 setzt.

Um das Beispiel von superM zu korrigieren, nehmen wir an, Sie haben eine LinearLayoutmit horizontaler Ausrichtung, die zwei ImageViewsund eine TextViewmit enthält. Sie definieren TextVieweine feste Größe, und Sie möchten, dass die beiden ImageViewsden verbleibenden Platz gleichmäßig einnehmen.

Um dies zu erreichen, würden Sie layout_weightjeweils 1 auf jede anwenden ImageView, keine auf die TextViewund eine weightSumvon 2,0 auf dieLinearLayout .

Jeff Axelrod
quelle
20

Nach einigen Experimenten denke ich, dass der Algorithmus für LinearLayout folgendermaßen lautet:

Annehmen, dass weightSum ist auf einen Wert festgelegt. Der Fall der Abwesenheit wird später besprochen.

Teilen Sie zunächst die weightSumdurch die Anzahl der Elemente mit match_parentoder fill_parentin der Dimension des LinearLayout (z . B. layout_widthfür orientation="horizontal"). Wir werden diesen Wert den Gewichtsmultiplikator w_mfür jedes Element nennen. Der Standardwert für weightSum1,0 ist , so das Standardgewicht - Multiplizierer ist 1/n, wobei ndie Anzahl der fill_parentElemente; wrap_contentElemente tragen nicht dazu bei n.

w_m = weightSum / #fill_parent

Wenn weightSumbeispielsweise 60 ist und 3 fill_parentElemente vorhanden sind , ist der Gewichtsmultiplikator 20. Der Gewichtsmultiplikator ist der Standardwert für z. B. layout_widthwenn das Attribut fehlt.

Zweitens wird die maximal mögliche Ausdehnung jedes Elements berechnet. Zunächst werden die wrap_contentElemente nach ihrem Inhalt berechnet. Ihre Erweiterung wird von der Erweiterung des übergeordneten Containers abgezogen. Wir werden den Verbleibenden anrufen expansion_remainer. Dieser Rest verteilt sich auf die fill_parentElemente entsprechend ihrerlayout_weight .

Drittens wird die Erweiterung jedes fill_parentElements wie folgt berechnet:

w_m - (layout_weight / w_m) * maximum_possible_expansion

Beispiel:

Wenn weightSum60 ist und es 3 fill_parentElemente mit den Gewichten 10, 20 und 30 gibt, beträgt ihre Erweiterung auf dem Bildschirm 2/3, 1/3 und 0/3 des übergeordneten Containers.

weight | expansion
     0 | 3/3
    10 | 2/3
    20 | 1/3
    30 | 0/3
    40 | 0/3

Die minimale Ausdehnung ist auf 0 begrenzt. Die maximale Ausdehnung ist auf die übergeordnete Größe begrenzt, dh die Gewichte sind auf 0 begrenzt.

Wenn ein Element auf eingestellt wrap_contentist, wird zuerst seine Erweiterung berechnet, und die verbleibende Erweiterung wird auf die fill_parentElemente verteilt. Wenn weightSumgesetzt, hat dies layout_weightkeine Auswirkung auf wrap_contentElemente. Allerdings wrap_contentkönnen immer noch Elemente durch Elemente , dessen Gewicht niedriger ist als geschoben aus dem sichtbaren Bereich sein Gewichtsmultiplikator(beispielsweise zwischen 0-1 fürweightSum = 1 oder zwischen 0-20 für das obige Beispiel).

Wenn no weightSumangegeben wird, wird es als die Summe aller layout_weightWerte berechnet, einschließlich der Elemente mit wrap_contentset! Also haben layout_weightam Set wrap_contentElemente, können ihre Expansion beeinflussen. Zum Beispiel schrumpft ein negatives Gewicht die anderen fill_parentElemente. Bevor die fill_parentElemente angeordnet werden, wird die obige Formel auf wrap_contentElemente angewendet , wobei die maximal mögliche Erweiterung ihre Erweiterung entsprechend dem umhüllten Inhalt ist. Die wrap_contentElemente werden verkleinert und anschließend wird die maximal mögliche Erweiterung für die verbleibenden fill_parentElemente berechnet und verteilt.

Dies kann zu nicht intuitiven Ergebnissen führen.

Jens Jensen
quelle
10

Wenn nicht angegeben, wird die Summe berechnet, indem das layout_weight aller untergeordneten Elemente hinzugefügt wird. Dies kann zum Beispiel verwendet werden, um einem einzelnen Kind 50% des gesamten verfügbaren Speicherplatzes zu geben, indem es ein layout_weight von 0,5 gibt und die weightSum auf 1,0 setzt. Muss ein Gleitkommawert sein, z. B. "1.2"

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/main_rel"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal"
        android:weightSum="2.0" >

        <RelativeLayout
            android:id="@+id/child_one"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1.0"
            android:background="#0000FF" >
        </RelativeLayout>

        <RelativeLayout
            android:id="@+id/child_two"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1.0"
            android:background="#00FF00" >
        </RelativeLayout>

    </LinearLayout>
Faakhir
quelle
'Kann ein Gleitkommawert sein, z. B. "1.2".' ( developer.android.com/reference/android/widget/… )
Der unglaubliche
6

Eine Sache, die anscheinend niemand anderes erwähnt hat: Nehmen wir an, Sie haben eine Vertikale LinearLayout . Damit die Gewichte in Layout / Element / Ansicht darin 100% richtig funktionieren, müssen alle layout_heightEigenschaften haben (die in Ihrer XML vorhanden sein müssen) Datei) gesetzt auf 0dp. Scheint, als würde jeder andere Wert in einigen Fällen die Dinge durcheinander bringen.

Yoav Feuerstein
quelle
1
android: layout_width = "match_parent" wird normalerweise anstelle von 0dp
kc ochibili
Warum ist das so? Ich meine, Sie haben Recht, es ist durcheinander, aber die Einstellung der Höhe auf 0 dp hat mein Problem gelöst. Ich würde den Grund kennen.
Abdul Waheed
2

Das Layoutgewicht funktioniert wie ein Verhältnis. Wenn beispielsweise ein vertikales Layout vorhanden ist und zwei Elemente (z. B. Schaltflächen oder Textansichten) vorhanden sind, hat eines das Layoutgewicht 2 und das andere das Layoutgewicht 3. Dann belegt das erste Element 2 von 5 Teilen des Bildschirms / Layouts und das andere 3 von 5 Teilen. Hier ist 5 die Gewichtssumme. dh die Gewichtssumme unterteilt das gesamte Layout in definierte Teile. Und Layoutgewicht definiert, wie viel Teil der jeweiligen Artikel von der vordefinierten Gesamtgewichtssumme einnimmt. Die Gewichtssumme kann auch manuell deklariert werden. Schaltflächen, Textansichten, Edittexte usw. werden bei Verwendung linearer Layouts für das UI-Design nach Gewichtssumme und Layoutgewicht organisiert.

Sami Al-Jabar
quelle
1

Aus Entwicklerdokumentation

Dies kann zum Beispiel verwendet werden, um einem einzelnen Kind 50%den gesamten verfügbaren Speicherplatz zuzuweisen, indem es ein layout_weight von 0.5und die weightSum auf setzt 1.0.

Ergänzung zu @ Shubhayu Antwort

rest 3/5kann für andere untergeordnete Layouts verwendet werden, für die wirklich kein bestimmter Teil des enthaltenen Layouts erforderlich ist.

Dies ist eine potenzielle Nutzung von android:weightSumEigentum.

DjP
quelle