Чому вкладені ваги погані для роботи? Альтернативи?


160

Я написав пару файлів компонування, де я використовував layout_weightатрибут для створення співвідношення між різними видами перегляду.

У якийсь момент я починаю отримувати попередження про вкладені ваги.

Отже, мені цікаво, чому вкладені ваги погані для продуктивності, і якщо існує більш ефективний спосіб створити постійне співвідношення між розмірами перегляду, які можна було б використовувати для різних розмірів екрана, і яким не потрібно вказувати велику величину розмірів dpi через декілька файлів компонування (я маю на увазі різний розмір екрана).

Дякую!


2
Дивовижна публікація для розробника
макета.android.com/training/improving-layouts/…

Відповіді:


140

Вкладені ваги погані для роботи, оскільки:

Ваги макета вимагають вимірювання віджета вдвічі. Коли LinearLayout з ненульовими вагами вкладений всередині іншого LinearLayout з ненульовими вагами, то кількість вимірювань збільшується в експоненціальному масштабі.

Краще використовувати RelativeLayout s і відрегулювати перегляд відповідно до місць інших переглядів, не використовуючи конкретні значення dpi.


87
Хороша річ, яку слід знати, якою я припускаю, є мета повідомлення. Я б відзначити , що експоненціальне вплив ще крихітне , якщо показник бере участь мало. Для невеликих глибин гніздування не використовувати необхідний для цього процесор - це як мати робочого коня, якого ви балуєте цілий тиждень і проводите лише для прогулянок по неділях. Тим не менш, для великих глибин гніздування це досить добре.
Карл

14
RelativeLayout також потрібно двічі виміряти, щоб переконатися, що всі його діти розміщують належним чином, тому зміна LinearLayout з вагою макета на RelativeLayout може не підвищити продуктивність.
Піасі

Відносна компонування не завжди працює. У випадках, коли вам потрібно побудувати пропорційні віджети
Абдурахмон

67

Оновлення: Як відомо, бібліотека відсотків підтримки застаріла від рівня API 26 ConstraintLayout- це новий спосіб досягти тієї ж плоскої XML-структури.

Оновлений проект Github

Оновлені зразки:

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

Оновлення: Прекрасна бібліотека підтримки андроїд-відсотків вирішує нашу проблему продуктивності та вкладених безладноLinearLayout

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

Демо ТУТ

Розглянемо цей простий макет, щоб продемонструвати те саме.

відсотків підтримки демонстрації бібліотеки

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

Уникайте деградатора продуктивності, який вкладається LinearLayoutз вагами.


@dan Так, враховуючи, що ми вклали лінійний макет з вагами.
нітеш

3
"Цей клас застарілий на рівні API 26.0.0-beta1. Розглянемо, замість цього використовувати ConstraintLayout та пов'язані з ним макети." developer.android.com/reference/android/support/percent/…
saiyancoder

7
Мені не подобається ConstraintLayout. Він не веде себе інтуїтивно
Карсон Хольцгеймер


1
можливо, пояснення, що даються яблуком щодо обмежень авторозмикання , чіткіші, і оскільки логіка однакова, це може допомогти. На жаль, я вважаю, що обмеження для
обмежених можливостей

46

Я думаю (і, мабуть, за це спалахнув би), але знову ж таки думаю, що в моєму телефоні є чотирьохядерний процесор, який може конкурувати (якщо не зовсім знищити) більшість народних домашніх ПК.

Я також думаю, що такий апаратний потенціал - це майбутнє телефонів.

Тож я прийшов до висновку, що поки ви не захоплюєтеся гніздуванням (у MHO макет ніколи не повинен бути глибше 4 рівнів, і якщо це, напевно, ви робите це неправильно), ваш телефон може менше турбуватися про наявність ваг.

Ви можете зробити багато речей, які матимуть набагато більш далекосяжний ефект на продуктивність, тож турбуєтесь про те, щоб ваш процесор займався додатковою математикою.

(будь ласка, зауважте, що я трохи жартівливий, і тому не сприймати щось надто серйозно з цієї посади, крім того, що ідея про те, що є інші речі, які слід спочатку оптимізувати, і що турбота про глибоку вагу на 2-3 рівні не допомагає твоє здоров'я)


2
прийнято, і по суті погоджуються, але чули, що середнє використання iphone (у тому числі веб-служб / веб-сайтів, які підтримують його використання) приблизно стільки ж енергії на рік, скільки і середній американський холодильник. Тому ми несемо відповідальність за розробників за врахування такого впливу на навколишнє середовище. Очевидно, що це завжди балансуючий акт: час, витрати, продуктивність, стабільність і, як правило, я згоден з вашою точкою зору - але просто думаю, що ми також повинні враховувати такий вплив. Очевидно, тут також входить технічне обслуговування / розширюваність. У будь-якому випадку - бал і спасибі.
MemeDeveloper

Зрозумійте, що конкретний питання йдеться про обробку на пристрої не в Інтернеті, але маю на увазі мій коментар як загальний пункт щодо пріоритетів як розробників більше, ніж специфіки ОП.
MemeDeveloper

11

Основна причина, чому вкладені ваги погані, полягає в тому, що коли у макеті є діти з вагою, його потрібно виміряти вдвічі (я думаю, це згадується в попередженні про ворсинки). Це означає, що зважений макет, який також містить зважений макет, повинен вимірюватися в чотири рази, і кожен доданий вами "шар" ваг збільшує міри потужністю в два.

У ICS (API рівень 14) GridLayoutдодано додаток, що дозволяє прості та «плоскі» рішення для багатьох макетів, які раніше вимагали зважування. Якщо ви розробляєте для більш ранніх версій Android, вам доведеться трохи важче зняти ваги, але, використовуючи RelativeLayoutякомога більшу площину своєї компоновки в цій кабіні, зазвичай видаляйте багато вкладених ваг.


9
Я не думаю, що ти можеш досягти однакових результатів за допомогою GridLayout або RelativeLayout . Напр . GridLayout: "GridLayout не підтримує принцип ваги, визначений у вазі. Загалом, таким чином, неможливо налаштувати GridLayout для розподілу зайвого простору між декількома компонентами."
Timmmm

Починаючи з API 21, поняття ваги було додано до GridLayout. Для підтримки старих пристроїв Android ви можете використовувати GridLayout з бібліотеки підтримки v7. android.support.v7.widget.GridLayout
Эвансгелист Евансгеліст

2

Існує просте рішення, щоб уникнути вкладених LinearLayouts з вагами - просто використовуйте Tablelayout з WeightSum і вкладений LinearLayout з weightSum - Tablelayout має ті ж атрибути, що і LinearLayout (орієнтація, weightSum, layout_weight тощо) і не показує повідомлення - "вкладені ваги мають погані показники "

Приклад:

 <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

Я думаю, єдиною альтернативою є створення функції, яка б називалася onResume і встановлюватиме всі розміри та позиції. У будь-якому випадку за вагою ви можете встановлювати лише розміри, але ніяких накладок (так макети стають ще складнішими), ніяких textSize (неможливо це якось компенсувати), не кажучи вже про такі речі, як кількість рядків.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.