İç içe ağırlıklar performans için neden kötüdür? Alternatifler?


160

layout_weightFarklı görünümler arasında bir oran oluşturmak için özniteliği kullandığım birkaç düzen dosyası yazdım .

Bir noktada, iç içe ağırlıklar hakkında tüysüz uyarılar almaya başlıyorum.

Bu yüzden, neden iç içe geçmiş ağırlıkların performans için kötü olduğunu ve farklı ekran boyutları için kullanılabilecek ve çok fazla boyut dpi değeri belirtmesi gerekmeyen görünüm boyutları arasında sabit bir oran oluşturmanın daha etkili bir yolu varsa merak ediyorum birkaç düzen dosyası düşündüm (farklı ekran boyutları için, yani).

Teşekkür ederim!


Yanıtlar:


140

İç içe ağırlıklar performans için kötüdür çünkü:

Düzen ağırlıkları, bir widget'ın iki kez ölçülmesini gerektirir. Sıfır olmayan ağırlığa sahip bir LinearLayout, sıfır olmayan ağırlığa sahip başka bir LinearLayout içine yerleştirildiğinde, ölçüm sayısı katlanarak artar.

RelativeLayout'ları kullanmak ve belirli dpi değerleri kullanmadan görünümünüzü diğer görünümlerin yerlerine göre ayarlamak daha iyidir .


87
Farkında olmak iyi bir şey, sanırım mesajın amacı budur. Ben ediyorum dahil üs küçükse üstel etkisi hala küçük olduğunu unutmayın. İçin yuvalama küçük derinliği için, değil CPU kullanmak bu her hafta şımartmak sen misin bir beygir olan ve sadece Pazar günleri yürüyüşe dışarı kurşun gibidir yapmak için gerekli. Yine de, büyük yuvalama derinlikleri için, bu iyi bir nokta.
Carl

14
RelativeLayout, tüm çocuklarının düzgün bir şekilde yerleştiğinden emin olmak için iki kez ölçüme ihtiyaç duyar, bu nedenle düzen ağırlığına sahip LinearLayout'u RelativeLayout olarak değiştirmek performansı iyileştirmeyebilir.
Piasy

Göreceli düzen her zaman çalışmaz. Orantılı widget'lar oluşturmanız gereken durumlarda
Abdurakhmon

67

Güncelleme: Bildiğimiz gibi, destek kütüphanesi yüzde 26 API seviyesinden kaldırılmıştır ConstraintLayout. Aynı düz xml yapısını elde etmenin yeni yoludur.

Güncellenmiş Github Projesi

Güncellenmiş Örnekler:

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

Güncelleme: Harika haber android yüzde destek kütüphanesi performans sorunumuzu ve iç içe dağınık ağırlıklı çözerLinearLayout

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

BURAYA Demo

Aynı şeyi göstermek için bu basit düzeni düşünün.

yüzde libray demo desteği

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

Ağırlıklar LinearLayoutile iç içe performans degrader kaçınılmaz .


@dan Evet, doğrusal düzeni ağırlıklarla iç içe geçirdiğimizi düşünüyoruz.
nitesh

3
"Bu sınıf API 26.0.0-beta1 düzeyinde kullanımdan kaldırıldı. Bunun yerine ConstraintLayout ve ilişkili mizanpajları kullanmayı düşünün." developer.android.com/reference/android/support/percent/…
saiyancoder

7
ConstraintLayout'u sevmiyorum. Benim için sezgisel davranmıyor
Carson Holzheimer

8
ConstraintLayout benim için çok zor
BertKing

1
belki elma tarafından otomatik yerleşim kısıtlamalarında verilen açıklamalar daha açıktır ve mantık aynı olduğundan yardımcı olabilir. Ne yazık ki
droid'in

46

Sanırım (ve muhtemelen bunun için alevleneceğim), ama yine de telefonumun çoğu evdeki PC'lere rakip olmak için (tamamen yok etmiyorsa) dört çekirdekli bir işlemci olduğunu düşünüyorum.

Ben de bu tür donanım yeteneklerinin telefonların geleceği olduğunu düşünüyorum.

Sonuç olarak, iç içe geçmekten uzak durmadığınız sürece (MHO'da bir düzen asla 4 seviyeden daha derin olmamalıdır ve eğer muhtemelen yanlış yapıyorsanız), telefonunuz daha az bakım yapabilir ağırlık sahibi olmak.

Performans üzerinde çok daha geniş bir etkiye sahip olacak, daha sonra işlemcinizin ekstra matematik yapması konusunda endişelenecek yapabileceğiniz birçok şey var.

(lütfen biraz esprili olduğumu ve bu yazıdan çok ciddiye almamaya dikkat edin, aksi takdirde önce optimize etmeniz gereken başka şeyler olduğu ve 2-3 seviyeli derin bir kilo hakkında endişelenmenize yardımcı olmama sağlığın)


2
alınan ve esasen katılıyorum, ancak ortalama iphone kullanımlarının (kullanımını destekleyen web hizmetleri / sitesi dahil) ortalama ABD ev buzdolabı ile yılda aynı miktarda enerji duyduğunu duydum. Bu nedenle, bu tür çevresel etkileri dikkate almak geliştiriciler olarak bizim sorumluluğumuzdur. Açıkçası bu her zaman dengeleyici bir eylemdir: zaman, maliyetler, performans, istikrar ve genel olarak bakış açınıza katılıyorum - ama sadece bu tür bir etkiyi de düşünmemiz gerektiğini düşünüyorum. Açıkçası bakım / genişletilebilirlik de buraya geliyor. Her neyse - nokta yapılmış ve teşekkürler.
MemeDeveloper

Söz konusu özel noktanın, web üzerinde değil, cihaz üzerinde işlem yapmakla ilgili olduğunu, ancak geliştiricilerin OP'nin özelliklerinden daha fazla öncelikler hakkında genel bir nokta olarak yorumumu ifade ettiğini anlıyorum.
MemeDeveloper

11

İç içe geçmiş ağırlıkların kötü olmasının temel nedeni, bir düzenin ağırlığı olan çocuklar olduğunda, iki kez ölçülmesi gerektiğidir (bence bu tüysüz uyarıda belirtilmiştir). Bu, aynı zamanda, ağırlıklı bir düzen içeren ağırlıklı bir düzenin dört kez ölçülmesi gerektiği ve eklediğiniz ağırlıkların her bir "katmanı", ölçümleri iki güçle arttırır.

ICS'de (API seviye 14), GridLayoutdaha önce ağırlık gerektiren birçok düzen için basit ve 'düz' çözümlere izin veren eklenmiştir. Android'in önceki sürümleri için geliştiriyorsanız, ağırlıkları kaldırmak için biraz daha zor zamanınız olacaktır, ancak RelativeLayoutmizanpajınızı o kabine mümkün olduğunca düzleştirmek ve genellikle iç içe ağırlıkların çoğunu kaldırmak.


9
GridLayout Veya ile aynı sonuçları elde edebileceğinizi sanmıyorum RelativeLayout. Örneğin GridLayout: "GridLayout, ağırlık olarak tanımlandığı gibi ağırlık prensibi için destek sağlamaz. Bu nedenle, genel olarak, bir GridLayout'u birden fazla bileşen arasında fazla alan dağıtacak şekilde yapılandırmak mümkün değildir."
Timmmm

API 21'den başlayarak ağırlık kavramı GridLayout'a eklendi. Eski android cihazları desteklemek için, v7 destek kütüphanesinden GridLayout'u kullanabilirsiniz. android.support.v7.widget.GridLayout
Эвансгелист Evansgelist

2

Yuvalanmış LinearLayouts'u ağırlıklarla önlemek için kolay bir çözüm var - sadece tartma toplamı ile Tablelayout ve weightSum ile iç içe LinearLayout kullanın - Tablelayout, LinearLayout ile aynı özelliklere sahiptir (yönlendirme, weightSum, layout_weight, vb.) Ve mesaj göstermez - "iç içe ağırlıklar performans için kötü "

Misal:

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

1

Bence, tek alternatif onResume denilen ve tüm boyutları ve konumları ayarlayacak bir işlev yapmaktır. Her neyse, ağırlık olarak sadece boyutlar ayarlayabilirsiniz, ancak dolgu yoktur (bu nedenle düzenler daha da karmaşık hale gelir), textSize's (bunu bir şekilde telafi etmek imkansızdır), satır sayısı gibi şeyleri bir kenara bırakın.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.