Mengapa bobot bersarang buruk untuk kinerja? Alternatif?

160

Saya telah menulis beberapa file tata letak tempat saya menggunakan layout_weightatribut untuk membuat rasio antara tampilan yang berbeda.

Pada titik tertentu, saya mulai mendapatkan peringatan serat tentang bobot bersarang.

Jadi, saya bertanya-tanya mengapa bobot bersarang buruk untuk kinerja, dan jika ada cara yang lebih efisien untuk membuat rasio konstan antara dimensi tampilan yang dapat digunakan untuk ukuran layar yang berbeda dan yang tidak perlu menentukan banyak dimensi nilai dpi beberapa file tata letak (untuk ukuran layar yang berbeda, maksud saya).

Terima kasih!

MobileCushion
sumber
2
Pos yang luar biasa untuk developer
Muhammad Babar

Jawaban:

140

Bobot bersarang buruk untuk kinerja karena:

Bobot tata letak membutuhkan widget untuk diukur dua kali. Ketika LinearLayout dengan bobot non-nol bersarang di dalam LinearLayout lain dengan bobot non-nol, maka jumlah pengukuran meningkat secara eksponensial.

Lebih baik menggunakan RelativeLayout s dan menyesuaikan tampilan Anda sesuai dengan tempat-tempat pandangan lain tanpa menggunakan nilai dpi tertentu.

CD
sumber
87
Hal yang baik untuk diperhatikan, yang saya duga adalah tujuan dari pesan tersebut. Saya akan mencatat bahwa dampak eksponensial masih kecil jika eksponen yang terlibat kecil. Untuk kedalaman sarang yang kecil, untuk tidak menggunakan CPU yang diperlukan untuk melakukan ini seperti memiliki pekerja keras yang Anda manjakan sepanjang minggu dan hanya berjalan-jalan di hari Minggu. Namun, untuk kedalaman sarang yang besar, ini adalah poin yang diambil dengan baik.
Carl
14
RelativeLayout juga perlu mengukur dua kali untuk memastikan semua tata letak anak-anaknya benar, jadi ubah LinearLayout dengan bobot tata letak menjadi RelativeLayout mungkin tidak meningkatkan kinerja.
Piasy
Tata letak relatif tidak selalu berfungsi. Dalam kasus di mana Anda perlu membuat widget proporsional
Abdurakhmon
67

Pembaruan: Seperti yang kita ketahui, pustaka dukungan persen tidak digunakan lagi di API level 26. ConstraintLayoutadalah cara baru untuk mencapai struktur flat xml yang sama.

Proyek Github yang Diperbarui

Sampel yang diperbarui:

<android.support.constraint.ConstraintLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/fifty_thirty"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="#ffff8800"
        android:gravity="center"
        android:text="@string/fifty_fifty_text"
        android:textColor="@android:color/white"
        app:layout_constraintHeight_default="percent"
        app:layout_constraintHeight_percent="0.5"
        android:textSize="25sp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintWidth_default="percent"
        app:layout_constraintWidth_percent="0.5" />

    <TextView
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="#ffff5566"
        android:gravity="center"
        android:text="@string/fifty_fifty_text"
        android:textColor="@android:color/white"
        android:textSize="25sp"
        app:layout_constraintHeight_default="percent"
        app:layout_constraintHeight_percent="0.5"
        app:layout_constraintLeft_toRightOf="@id/fifty_thirty"
        app:layout_constraintTop_toBottomOf="@id/fifty_thirty"
        app:layout_constraintWidth_default="percent"
        app:layout_constraintWidth_percent="0.5" />

</android.support.constraint.ConstraintLayout>

Pembaruan: Kabar baik android dukungan perpustakaan persen memecahkan masalah kinerja kami dan bersarang berantakan tertimbangLinearLayout

compile 'com.android.support:percent:23.0.0'

Demo DI SINI

Pertimbangkan tata letak sederhana ini untuk menunjukkan hal yang sama.

persen mendukung demo libray

<android.support.percent.PercentRelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/fifty_huntv"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="#ff7acfff"
        android:text="20% - 50%"
        android:textColor="@android:color/white"
        app:layout_heightPercent="20%"
        app:layout_widthPercent="50%" />
    <TextView
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_toRightOf="@id/fifty_huntv"
        android:background="#ffff5566"
        android:text="80%-50%"
        app:layout_heightPercent="80%"
        app:layout_widthPercent="50%"
        />

</android.support.percent.PercentRelativeLayout>

Penghindaran kinerja yang terhindar bersarang LinearLayoutdengan bobot. Sangat mengagumkan !!!.

nitesh
sumber
@dan Ya mengingat kami memiliki tata letak linear bersarang dengan bobot.
nitesh
3
"Kelas ini sudah tidak digunakan lagi di API level 26.0.0-beta1. Pertimbangkan menggunakan ConstraintLayout dan tata letak terkait sebagai gantinya." developer.android.com/reference/android/support/percent/…
saiyancoder
7
Saya tidak suka ConstraintLayout. Itu tidak berperilaku intuitif bagi saya
Carson Holzheimer
8
ConstraintLayout sangat sulit bagi saya
BertKing
1
mungkin penjelasan yang diberikan oleh apel tentang batasan autolayout lebih jelas, dan karena logikanya sama, itu bisa membantu. Sayangnya saya menemukan ConstraintLayout droid lebih berat / verbose untuk digunakan daripada iOS 'AutoLayout
AdricoM
46

Saya pikir (dan saya mungkin akan dinyalakan untuk ini), tetapi sekali lagi saya pikir ponsel saya memiliki prosesor quad core untuk menyaingi (jika tidak benar-benar menghancurkan) kebanyakan orang di rumah PC.

Saya juga berpikir kemampuan perangkat keras semacam ini adalah masa depan ponsel.

Jadi saya sampai pada kesimpulan, bahwa selama Anda tidak terbawa oleh sarang (dalam MHO tata letak tidak boleh lebih dari 4 level, dan jika Anda salah melakukannya), ponsel Anda bisa kurang peduli tentang memiliki bobot.

Ada banyak hal yang dapat Anda lakukan yang akan memiliki efek jangkauan jauh lebih jauh pada kinerja, kemudian mengkhawatirkan prosesor Anda melakukan beberapa matematika tambahan.

(harap dicatat bahwa saya menjadi sedikit lucu, jadi jangan menganggap serius posting ini, selain itu ada ide lain yang harus Anda optimalkan terlebih dahulu, dan mengkhawatirkan berat badan sekitar 2-3 level tidak membantu) kesehatanmu)

WIllJBD
sumber
2
diambil, dan pada dasarnya setuju, tetapi telah mendengar rata-rata penggunaan iphone (termasuk layanan web / situs yang mendukung penggunaannya) sekitar jumlah energi yang sama setahun dengan rata-rata kulkas rumah tangga AS. Karena itu merupakan tanggung jawab kami sebagai pengembang untuk mempertimbangkan dampak lingkungan semacam ini. Jelas itu selalu merupakan tindakan penyeimbang: waktu, biaya, kinerja, stabilitas, dan secara umum saya setuju dengan perspektif Anda - tetapi anggap saja kita juga harus mempertimbangkan dampak semacam ini. Jelas pemeliharaan / ekstensibilitas datang di sini juga. Bagaimanapun - point dibuat dan terima kasih.
MemeDeveloper
Menyadari titik spesifik yang dimaksud adalah tentang pemrosesan pada perangkat, bukan web, tetapi maksud komentar saya sebagai poin umum tentang prioritas sebagai pengembang lebih dari spesifikasi OP.
MemeDeveloper
11

Alasan utama mengapa bobot bersarang buruk adalah ketika tata letak memiliki anak dengan berat, itu harus diukur dua kali (saya pikir ini disebutkan dalam peringatan serat). Ini berarti bahwa tata letak berbobot yang juga berisi tata letak tertimbang harus diukur empat kali, dan setiap 'lapisan' bobot yang Anda tambahkan menambah ukuran dengan kekuatan dua.

Dalam ICS (API level 14) GridLayoutditambahkan, yang memungkinkan solusi sederhana dan 'rata' untuk banyak tata letak yang sebelumnya membutuhkan bobot. Jika Anda mengembangkan untuk versi Android yang lebih lama, Anda akan memiliki waktu yang sedikit lebih sulit untuk menghilangkan beban, tetapi menggunakan RelativeLayoutdan meratakan sebanyak mungkin tata letak Anda ke dalam kabin itu biasanya menghilangkan banyak beban yang bersarang.

Jave
sumber
9
Saya tidak berpikir Anda dapat mencapai hasil yang sama dengan GridLayout atau RelativeLayout . Misalnya untuk GridLayout: "GridLayout tidak memberikan dukungan untuk prinsip berat, seperti yang didefinisikan dalam berat. Secara umum, oleh karena itu, tidak mungkin untuk mengkonfigurasi GridLayout untuk mendistribusikan ruang berlebih di antara beberapa komponen."
Timmmm
Mulai di API 21 gagasan bobot ditambahkan ke GridLayout. Untuk mendukung perangkat Android yang lebih lama, Anda dapat menggunakan GridLayout dari perpustakaan dukungan v7. android.support.v7.widget.GridLayout
Эвансгелист Evansgelist
2

Ada solusi mudah untuk menghindari LinearLayout bersarang dengan bobot - cukup gunakan Tablelayout dengan weighSum dan LinearLayout bersarang dengan weightSum - Tablelayout memiliki atribut yang sama dengan LinearLayout (orientasi, weightSum, layout_weight, dll.) Dan tidak menampilkan pesan - "nested weights buruk untuk kinerja "

Contoh:

 <TableLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:weightSum="1">

        <ImageView
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="0.8"/>


        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="0.2"
            android:orientation="horizontal"
            android:weightSum="1">


            <ImageView
                android:layout_height="match_parent"
                android:layout_width="0dp"
                android:layout_weight="0.4"/>

            <TextView
                android:layout_height="match_parent"
                android:layout_width="0dp"
                android:layout_weight="0.6"/>


            </LinearLayout>

    </TableLayout>
eneyovich
sumber
1

Saya pikir, satu-satunya alternatif adalah membuat fungsi yang akan dipanggil padaResume dan akan mengatur semua ukuran dan posisi. Ngomong-ngomong, berdasarkan berat, Anda hanya dapat mengatur ukuran tetapi tanpa bantalan (sehingga tata letak menjadi lebih rumit), tanpa ukuran teks (mustahil untuk mengompensasi ini entah bagaimana), apalagi hal-hal seperti jumlah baris.

Gangnus
sumber