Che cos'è Android: weightSum in Android e come funziona?


Risposte:


133

Per documentazione, android:weightSumdefinisce la somma del peso massimo e viene calcolata come la somma layout_weightdi tutti i bambini se non specificata in modo esplicito.

Consideriamo un esempio con a LinearLayoutcon orientamento orizzontale e 3 ImageViewsal suo interno. Ora vogliamo che abbiano ImageViewssempre lo stesso spazio. Per raggiungere questo obiettivo, puoi impostare layout_weightciascuno di ImageViewsu 1 e il valore weightSumsarà calcolato per essere uguale a 3 come mostrato nel commento.

<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 è utile per visualizzare correttamente il layout per qualsiasi dispositivo, cosa che non accadrà se imposti direttamente larghezza e altezza.


145
Questa non è una spiegazione dello scopo di weightSum. Il comportamento nel tuo esempio sarebbe identico a weightSumomesso, e in effetti weightSum non dovrebbe essere specificato in quello scenario. La documentazione dice: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: "non dovrebbe" essere specificato? Perché? Non vedo motivo per questo. Quindi direi che non è necessario specificarlo.
Caw

17
@MarcoW .: Non deve essere specificato a causa della manutenibilità. Come ha detto Jeff, l'impostazione di weightSum in modo che sia uguale alla somma dei pesi all'interno del layout non compie nulla, ma se qualcuno lo modifica in futuro potrebbe causare mal di testa poiché ora c'è un modificatore non necessario al layout che dovrebbe essere trovato e cambiato. Questa risposta non è corretta e non dovrebbe essere la risposta accettata.
d370urn3ur,

3
Non vedo una buona spiegazione del parametro weightSum, quindi dai documenti: "Questo può essere usato ad esempio per dare a un singolo figlio il 50% dello spazio disponibile totale assegnandogli un layout_weight di 0,5 e impostando weightSum su 1.0". Vedi developer.android.com/reference/android/widget/…
Deepscorn

5
L'idea è che è possibile impostare weightSum su un numero superiore alla somma dei bambini. Questo fa sì che i bambini ricevano parte ma non tutto lo spazio extra disponibile. Nell'esempio sopra, il tuo bambino unico erediterebbe metà dello spazio disponibile invece di tutto.
Edward Falk,

175

Aggiungendo alla risposta di superM e Jeff,

Se ci sono 2 viste in LinearLayout, la prima con un layout_weight di 1, la seconda con un layout_weight di 2 e nessun peso è specificato, per impostazione predefinita, il peso è calcolato come 3 (somma dei pesi dei bambini) e la prima vista occupa 1/3 dello spazio mentre la seconda occupa 2/3.

Tuttavia, se dovessimo specificare weightSum come 5, il primo richiederebbe 1/5 dello spazio mentre il secondo richiederebbe 2/5. Quindi un totale di 3/5 dello spazio sarebbe occupato dal layout mantenendo il resto vuoto.


2
Stavo cercando lo stesso, che cosa accadrebbe se il peso non fosse definito e i pesi fossero forniti alle viste del bambino. La tua risposta che calcola da sola ha cancellato tutto
DeltaCap019

È vero che si consiglia di utilizzare RelativeLayout rispetto ai layout con weightSum?
Robert,

26

La somma dei pesi funziona esattamente come vuoi (come altre risposte, non devi sommare tutti i pesi sul layout principale). Nella vista figlio specificare il peso che si desidera assumere. Non dimenticare di specificare

android:layout_width="0dp" 

Di seguito è riportato un esempio

    <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>

Questo sembrerà

inserisci qui la descrizione dell'immagine


25

La documentazione lo dice meglio e include un esempio (evidenziando il mio).

Android: weightSum

Definisce la somma del peso massimo. Se non specificato, la somma viene calcolata aggiungendo il layout_weight di tutti i figli. Questo può essere usato ad esempio per dare a un singolo figlio il 50% dello spazio disponibile totale assegnandogli un layout_weight di 0,5 e impostando weightSum su 1.0.

Quindi, per correggere l'esempio di superM, supponiamo di avere un LinearLayoutorientamento orizzontale che contiene due ImageViewse un TextViewcon. Definisci TextViewdi avere una dimensione fissa e desideri che i due ImageViewsoccupino lo spazio rimanente allo stesso modo.

Per fare ciò, dovresti applicare layout_weight1 a ciascuno ImageView, nessuno sul TextView, e un weightSumdi 2.0 sul LinearLayout.


20

Dopo alcuni esperimenti, penso che l'algoritmo per LinearLayout sia questo:

Supponiamo che weightSumsia impostato su un valore. Il caso di assenza verrà discusso più avanti.

Innanzitutto, dividi il weightSumnumero per il numero di elementi con match_parento fill_parentnella dimensione del LinearLayout (ad esempio layout_widthper orientation="horizontal"). Chiameremo questo valore il moltiplicatore di peso w_mper ciascun elemento. Il valore predefinito per weightSum1.0 è, quindi il moltiplicatore di peso predefinito è 1/n, dove nè il numero di fill_parentelementi; wrap_contentgli elementi non contribuiscono a n.

w_m = weightSum / #fill_parent

Ad esempio, quando weightSumè 60 e vi sono 3 fill_parentelementi, il moltiplicatore di peso è 20. Il moltiplicatore di peso è il valore predefinito, ad esempio layout_widthse l'attributo è assente.

In secondo luogo, viene calcolata la massima espansione possibile di ogni elemento. Innanzitutto, gli wrap_contentelementi vengono calcolati in base al loro contenuto. La loro espansione viene dedotta dall'espansione del contenitore padre. Chiameremo il resto expansion_remainer. Questo resto è distribuito tra gli fill_parentelementi in base al loro layout_weight.

In terzo luogo, l'espansione di ogni fill_parentelemento viene calcolata come:

w_m - (layout_weight / w_m) * maximum_possible_expansion

Esempio:

Se weightSumè 60 e ci sono 3 fill_parentelementi con i pesi 10, 20 e 30, la loro espansione sullo schermo è 2/3, 1/3 e 0/3 del contenitore principale.

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

L'espansione minima è limitata a 0. L'espansione massima è limitata alla dimensione padre, ovvero i pesi sono limitati a 0.

Se un elemento è impostato su wrap_content, la sua espansione viene calcolata per prima e la restante espansione è soggetta alla distribuzione tra gli fill_parentelementi. Se weightSumimpostato, questo porta a layout_weightnon avere alcun effetto sugli wrap_contentelementi. Tuttavia, gli wrap_contentelementi possono ancora essere spinti fuori dall'area visibile da elementi il ​​cui peso è inferiore a moltiplicatore di peso(ad esempio tra 0-1 per weightSum= 1 o tra 0-20 per l'esempio sopra).

Se no weightSumviene specificato, viene calcolato come la somma di tutti i layout_weightvalori, inclusi gli elementi con wrap_contentset! Quindi, avendo layout_weightimpostato su wrap_contentelementi, può influenzare la loro espansione. Ad esempio un peso negativo ridurrà gli altri fill_parentelementi. Prima che gli fill_parentelementi siano disposti, la formula sopra sarà applicata agli wrap_contentelementi, con la massima espansione possibile la loro espansione in base al contenuto avvolto. Gli wrap_contentelementi verranno ridotti e successivamente fill_parentviene calcolata e distribuita la massima espansione possibile per gli elementi rimanenti .

Ciò può portare a risultati non intuitivi.


10

Se non specificato, la somma viene calcolata aggiungendo il layout_weight di tutti i figli. Questo può essere usato ad esempio per dare a un singolo figlio il 50% dello spazio disponibile totale assegnandogli un layout_weight di 0,5 e impostando weightSum su 1.0. Deve essere un valore in virgola mobile, ad esempio "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>

"Può essere un valore in virgola mobile, ad esempio" 1.2 "." ( developer.android.com/reference/android/widget/… )
L'incredibile

6

Una cosa che sembra che nessun altro abbia menzionato: diciamo che hai una verticale LinearLayout , quindi affinché i pesi nel layout / elemento / vista al suo interno funzionino correttamente al 100% - tutti devono avere layout_heightproprietà (che deve esistere nel tuo XML file) impostato su 0dp. Sembra che qualsiasi altro valore rovinerebbe le cose in alcuni casi.


1
android: layout_width = "match_parent" è di solito usato invece di 0dp
kc ochibili

perchè è così? Voglio dire, hai ragione, è incasinato, ma l'impostazione dell'altezza a 0 dp ha risolto il mio problema. vorrei sapere il motivo.
Abdul Waheed,

2

Il peso del layout funziona come un rapporto. Ad esempio, se esiste un layout verticale e ci sono due elementi (come pulsanti o visualizzazioni di testo), uno con peso di layout 2 e l'altro con peso di layout 3 rispettivamente. Quindi il primo elemento occuperà 2 parti su 5 dello schermo / layout e l'altra 3 parti su 5. Qui 5 è la somma dei pesi. cioè la somma dei pesi divide l'intero layout in porzioni definite. E il peso del layout definisce la parte occupata dall'elemento specifico rispetto alla somma totale del peso predefinita. Anche la somma dei pesi può essere dichiarata manualmente. Pulsanti, visualizzazioni di testo, edizioni, ecc. Sono tutti organizzati utilizzando pesi e peso del layout quando si utilizzano layout lineari per la progettazione dell'interfaccia utente.


1

Dalla documentazione per gli sviluppatori

Questo può essere usato ad esempio per dare a un singolo figlio 50%lo spazio disponibile totale assegnandogli un layout_weight di 0.5e impostando weightSum su 1.0.

Aggiunta alla risposta @Shubhayu

il resto 3/5può essere usato per altri layout secondari che in realtà non richiedono alcuna porzione specifica di layout di contenimento.

questo è un potenziale utilizzo di android:weightSum proprietà.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.