Apa itu android: weightSum di android, dan bagaimana cara kerjanya?

Jawaban:

132

Per dokumentasi, android:weightSummenentukan jumlah berat maksimum, dan dihitung sebagai jumlah layout_weightdari semua anak jika tidak ditentukan secara eksplisit.

Mari kita perhatikan contoh dengan LinearLayoutorientasi horizontal dan 3 ImageViewsdi dalamnya. Sekarang kami ingin ini ImageViewsselalu mengambil ruang yang sama. Untuk mencapai ini, Anda dapat mengatur layout_weightmasing-masing ImageViewke 1 dan weightSumakan dihitung sama dengan 3 seperti yang ditunjukkan dalam komentar.

<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 berguna untuk membuat tata letak ditampilkan dengan benar untuk perangkat apa pun, yang tidak akan terjadi jika Anda mengatur lebar dan tinggi secara langsung.

superM
sumber
145
Ini bukan penjelasan tentang tujuan weightSum. Perilaku dalam contoh Anda akan identik dengan weightSumdihilangkan, dan sebenarnya weightSum tidak boleh ditentukan dalam skenario itu. The dokumentasi mengatakan,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: "Tidak seharusnya" ditentukan? Mengapa? Saya tidak melihat alasan untuk itu. Jadi saya hanya akan mengatakan itu tidak perlu ditentukan.
gak
17
@ MarscoW .: Tidak boleh ditentukan karena rawatan. Seperti yang dikatakan Jeff, pengaturan bobotSum agar sama dengan jumlah bobot di dalam tata letak tidak menghasilkan apa-apa, tetapi jika seseorang mengubahnya di masa depan, hal itu dapat menyebabkan sakit kepala karena sekarang ada pengubah tata letak yang tidak perlu yang harus ditemukan dan berubah. Jawaban ini salah dan seharusnya bukan jawaban yang diterima.
d370urn3ur
3
Tidak melihat penjelasan yang baik tentang parameter weightSum, jadi dari dokumen: "Ini dapat digunakan misalnya untuk memberikan satu anak 50% dari total ruang yang tersedia dengan memberinya layout_weight 0,5 dan mengatur weightSum 1,0." Lihat developer.android.com/reference/android/widget/…
Deepscorn
5
Idenya adalah bahwa Anda dapat mengatur bobot ke angka yang lebih tinggi dari jumlah anak-anak. Ini menyebabkan anak-anak menerima sebagian tetapi tidak semua ruang ekstra yang tersedia. Pada contoh di atas, anak lajang Anda akan mewarisi setengah dari ruang yang tersedia alih-alih semuanya.
Edward Falk
175

Menambahkan ke jawaban superM dan Jeff,

Jika ada 2 tampilan di LinearLayout, yang pertama dengan layout_weight dari 1, yang kedua dengan layout_weight dari 2 dan tidak ada weightSum yang ditentukan, secara default, weightSum dihitung menjadi 3 (jumlah bobot anak-anak) dan tampilan pertama mengambil 1/3 dari ruang sedangkan yang kedua mengambil 2/3.

Namun, jika kita menentukan beratnya sebagai 5, yang pertama akan mengambil 1/5 dari ruang sementara yang kedua akan mengambil 2/5. Jadi total 3/5 ruang akan ditempati oleh tata letak menjaga sisanya kosong.

Shubhayu
sumber
2
Saya mencari yang sama, bahwa bagaimana jika weightsum tidak didefinisikan dan bobot disediakan untuk pandangan anak. Jawaban Anda bahwa itu menghitung sendiri semuanya dibersihkan
DeltaCap019
Benarkah disarankan menggunakan RelativeLayout daripada Layout dengan weightSum?
Robert
26

Jumlah bobot bekerja persis seperti yang Anda inginkan (seperti jawaban lain Anda tidak harus menjumlahkan semua bobot pada tata letak induk). Pada tampilan anak, tentukan berat yang Anda inginkan. Jangan lupa untuk menentukan

android:layout_width="0dp" 

Berikut ini adalah contohnya

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

Ini akan terlihat seperti

masukkan deskripsi gambar di sini

asok Buzz
sumber
25

The dokumentasi mengatakan itu yang terbaik dan termasuk contoh, (menyoroti saya).

android: weightSum

Menentukan jumlah berat maksimum. Jika tidak ditentukan, jumlah dihitung dengan menambahkan layout_weight dari semua anak. Ini dapat digunakan misalnya untuk memberikan anak tunggal 50% dari total ruang yang tersedia dengan memberinya layout_weight 0,5 dan mengatur weightSum menjadi 1,0.

Jadi untuk mengoreksi contoh superM, misalkan Anda memiliki LinearLayoutorientasi horizontal yang berisi dua ImageViewsdan TextViewdengan. Anda menentukan TextViewmemiliki ukuran tetap, dan Anda ingin keduanya ImageViewsuntuk mengambil ruang yang tersisa sama.

Untuk mencapai ini, Anda akan menerapkan layout_weight1 untuk masing-masing ImageView, tidak ada pada TextView, dan a weightSumdari 2.0 pada LinearLayout.

Jeff Axelrod
sumber
20

Setelah beberapa percobaan, saya pikir algoritma untuk LinearLayout adalah ini:

Asumsikan bahwa weightSumitu diatur ke nilai. Kasus ketidakhadiran dibahas kemudian.

Pertama, bagi weightSumdengan jumlah elemen dengan match_parentatau fill_parentdalam dimensi LinearLayout (misalnya layout_widthuntuk orientation="horizontal"). Kami akan menyebut nilai ini pengganda bobot w_muntuk setiap elemen. Nilai default untuk weightSumadalah 1.0, jadi pengganda bobot default adalah 1/n, di mana njumlah fill_parentelemen; wrap_contentelemen tidak berkontribusi n.

w_m = weightSum / #fill_parent

Misalnya kapan weightSum60, dan ada 3 fill_parentelemen, pengali berat adalah 20. Pengganda berat adalah nilai default untuk misalnya layout_widthjika atribut tidak ada.

Kedua, ekspansi maksimum yang mungkin dari setiap elemen dihitung. Pertama, wrap_contentelemen dihitung sesuai dengan isinya. Ekspansi mereka dikurangkan dari ekspansi wadah induk. Kami akan memanggil petugas expansion_remainer. Sisanya didistribusikan di antara fill_parentelemen - elemen sesuai dengan mereka layout_weight.

Ketiga, perluasan setiap fill_parentelemen dihitung sebagai:

w_m - (layout_weight / w_m) * maximum_possible_expansion

Contoh:

Jika weightSum60, dan ada 3 fill_parentelemen dengan bobot 10, 20 dan 30, ekspansi mereka di layar adalah 2/3, 1/3 dan 0/3 dari wadah induk.

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

Ekspansi minimum dibatasi pada 0. Ekspansi maksimum dibatasi pada ukuran induk, yaitu bobot dibatasi pada 0.

Jika elemen diatur ke wrap_content, ekspansi dihitung terlebih dahulu, dan ekspansi sisanya tunduk pada distribusi di antara fill_parentelemen. Jika weightSumdiatur, ini menyebabkan layout_weighttidak berpengaruh pada wrap_contentelemen. Namun, wrap_contentelemen masih dapat didorong keluar dari area yang terlihat oleh elemen yang beratnya lebih rendah dari pengganda berat(misalnya antara 0-1 untuk weightSum= 1 atau antara 0-20 untuk contoh di atas).

Jika tidak weightSumditentukan, itu dihitung sebagai jumlah dari semua layout_weightnilai, termasuk elemen dengan wrap_contentset! Jadi setelah layout_weightmenetapkan wrap_contentelemen, dapat mempengaruhi ekspansi mereka. Misalnya, bobot negatif akan mengecilkan fill_parentelemen lainnya . Sebelum fill_parentelemen diletakkan, akankah formula di atas diterapkan pada wrap_contentelemen, dengan kemungkinan ekspansi maksimum sesuai dengan konten yang dibungkus. The wrap_contentelemen akan menyusut, dan setelah itu mungkin ekspansi maksimum untuk sisa fill_parentelemen dihitung dan didistribusikan.

Ini dapat menyebabkan hasil yang tidak intuitif.

Jens Jensen
sumber
10

Jika tidak ditentukan, jumlah dihitung dengan menambahkan layout_weight dari semua anak. Ini dapat digunakan misalnya untuk memberikan anak tunggal 50% dari total ruang yang tersedia dengan memberinya layout_weight 0,5 dan mengatur weightSum menjadi 1,0. Harus berupa nilai titik apung, seperti "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
sumber
'Mungkin nilai floating point, seperti "1.2".' ( developer.android.com/reference/android/widget/… )
The Jan
6

Satu hal yang tampaknya seperti tidak ada orang lain yang disebutkan: katakanlah Anda memiliki vertikal LinearLayout , sehingga agar bobot dalam tata letak / elemen / view di dalamnya bekerja 100% benar - semua dari mereka harus memiliki layout_heightproperti (yang harus ada dalam xml Anda file) diatur ke 0dp. Sepertinya nilai lain akan mengacaukan segalanya dalam beberapa kasus.

Yoav Feuerstein
sumber
1
android: layout_width = "match_parent" biasanya digunakan sebagai ganti 0dp
kc ochibili
kenapa begitu? Maksud saya Anda benar itu mengacaukan, tetapi pengaturan tinggi ke 0 dp melihat masalah saya. Saya ingin tahu alasannya.
Abdul Waheed
2

Layout Weight berfungsi seperti rasio. Misalnya, jika ada tata letak vertikal dan ada dua item (seperti tombol atau tampilan teks), satu memiliki bobot tata letak 2 dan lainnya memiliki bobot tata letak 3 masing-masing. Maka item pertama akan menempati 2 dari 5 bagian layar / tata letak dan yang lainnya 3 dari 5 bagian. Di sini 5 adalah jumlah berat. yaitu jumlah Berat membagi seluruh tata letak menjadi beberapa bagian yang ditentukan. Dan Layout Weight menentukan seberapa banyak porsi item tertentu dari total Bobot yang ditentukan sebelumnya. Jumlah berat dapat dinyatakan secara manual juga. Tombol, tampilan teks, edittext, dll. Semua diatur menggunakan bobot dan bobot tata letak saat menggunakan tata letak linier untuk desain UI.

Sami Al-Jabar
sumber
1

Dari dokumentasi pengembang

Ini dapat digunakan misalnya untuk memberikan satu anak 50%dari total ruang yang tersedia dengan memberinya layout_weight of 0.5dan mengatur weightSum ke 1.0.

Tambahan untuk jawaban @Shubhayu

sisanya 3/5dapat digunakan untuk tata letak anak lain yang benar-benar tidak memerlukan bagian tertentu dari tata letak yang mengandung.

ini adalah potensi penggunaan android:weightSumproperti.

DjP
sumber