Распространено заблуждение, что использование базовых структур макета приводит к созданию наиболее эффективных макетов. Однако каждый виджет и макет, который вы добавляете в свое приложение, требуют инициализации, макета и рисования. Например, использование вложенных экземпляров LinearLayout
может привести к чрезмерно глубокой иерархии представлений. Кроме того, вложение нескольких экземпляров LinearLayout
, использующих параметр layout_weight
, может быть особенно дорогостоящим, поскольку каждый дочерний элемент необходимо измерять дважды. Это особенно важно, когда макет многократно раздувается, например, при использовании в RecyclerView
.
В этом документе показано, как использовать Layout Inspector и lint для проверки и оптимизации макета.
Проверьте свой макет
Инструменты Android SDK включают инструмент Layout Inspector , который позволяет анализировать макет во время работы приложения. Использование этого инструмента поможет вам обнаружить недостатки в производительности макета.
Инспектор макетов позволяет выбирать запущенные процессы на подключенном устройстве или эмуляторе, а затем отображать дерево макетов. Светофоры на каждом блоке отображают его производительность «Измерение», «Разметка» и «Рисование», помогая выявить потенциальные проблемы.
Например, на рис. 1 показан макет, который используется в качестве элемента в RecyclerView
. Этот макет показывает небольшое растровое изображение слева и два расположенных друг над другом элемента текста справа. Особенно важно, чтобы такие макеты, которые многократно раздуваются, были оптимизированы, поскольку при этом увеличивается выигрыш в производительности.
![Изображение, показывающее один элемент в списке: одно изображение и два вертикально выровненных текста.](https://developer.android.google.cn/static/images/training/layout-listitem.png?authuser=9&hl=ru)
RecyclerView
.Инспектор макетов показывает список доступных устройств и их работающих компонентов. Выберите компонент на вкладке «Окна» и нажмите «Инспектор макетов» , чтобы просмотреть иерархию макета выбранного компонента. Например, на рисунке 2 показан макет элемента списка, показанного на рисунке 1.
![Изображение, показывающее Layout Inspector и композицию LinearLayout.](https://developer.android.google.cn/static/images/training/hierarchy-linearlayout.png?authuser=9&hl=ru)
LinearLayout
.Пересмотрите свой макет
Поскольку производительность предыдущего макета снижается из-за вложенного LinearLayout
, вы можете повысить производительность, сгладив макет — другими словами, сделав макет неглубоким и широким, а не узким и глубоким. ConstraintLayout
в качестве корневого узла позволяет использовать такие макеты. Когда вы преобразуете этот дизайн для использования ConstraintLayout
, макет становится двухуровневой иерархией:
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/root" android:layout_width="match_parent" android:layout_height="52dp" android:background="#e4e6e4" android:padding="4dp"> <ImageView android:id="@+id/image" android:layout_width="48dp" android:layout_height="48dp" android:background="#5c5c74" android:contentDescription="An example box" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <TextView android:id="@+id/title" android:layout_width="0dp" android:layout_height="0dp" android:layout_marginStart="4dp" android:background="#745c74" app:layout_constraintBottom_toTopOf="@+id/subtitle" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@id/image" app:layout_constraintTop_toTopOf="parent" /> <TextView android:id="@+id/subtitle" android:layout_width="0dp" android:layout_height="0dp" android:background="#7e8d6e" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="@id/title" app:layout_constraintTop_toBottomOf="@+id/title" /> </androidx.constraintlayout.widget.ConstraintLayout>
Осмотр новой планировки выглядит так:
![Изображение, показывающее Инспектор 3D-макетов.](https://developer.android.google.cn/static/images/training/layout_inspector.png?authuser=9&hl=ru)
Преимущества этого многократно увеличиваются, поскольку этот макет используется для каждого элемента списка.
Большая часть разницы связана с использованием layout_weight
в конструкции LinearLayout
, который может замедлить измерение. Это один из примеров того, как каждый макет имеет подходящее применение. Тщательно подумайте, необходимо ли использовать вес макета.
В некоторых сложных макетах система может тратить усилия на измерение одного и того же элемента пользовательского интерфейса более одного раза. Это явление называется двойным налогообложением . Дополнительные сведения о двойном налогообложении и способах его предотвращения см. в разделе Эффективность и просмотр иерархий .
Используйте ворс
Хорошей практикой является запуск инструмента проверки файлов макета для поиска возможных оптимизаций иерархии представлений. Lint заменяет инструмент Layoutopt и имеет большую функциональность. Ниже приведены примеры правил lint:
- Используйте составные чертежи. Вы можете более эффективно обрабатывать
LinearLayout
, содержащийImageView
иTextView
, как составной объект рисования. - Объединить корневой фрейм. Если корнем макета является
FrameLayout
, который не предоставляет фона или заполнения, вы можете заменить его тегом слияния, что немного более эффективно. - Удалите ненужные листья. Вы можете удалить макет, у которого нет дочерних элементов или фона (поскольку он невидим), для более плоской и эффективной иерархии макетов.
- Уберите бесполезных родителей. Вы можете удалить макет с дочерним элементом, у которого нет одноуровневых элементов, который не является
ScrollView
или корневым макетом и не имеет фона. Вы также можете переместить дочернее представление непосредственно в родительское для более плоской и эффективной иерархии макета. - Избегайте глубоких макетов. Макеты со слишком большим количеством вложений плохо влияют на производительность. Рассмотрите возможность использования более плоских макетов, таких как
ConstraintLayout
, для повышения производительности. Максимальная глубина проверки на наличие ворса по умолчанию равна 10.
Еще одним преимуществом инструмента lint является его интеграция в Android Studio. Lint автоматически запускается при каждой компиляции программы. С помощью Android Studio вы также можете запускать проверки на наличие ворсинок для определенного варианта сборки или для всех вариантов сборки.
Вы также можете управлять профилями проверок и настраивать проверки в Android Studio с помощью параметра «Файл» > «Настройки» > «Настройки проекта» . Откроется страница конфигурации проверки с поддерживаемыми проверками:
![Изображение, показывающее меню проверок Android Studio.](https://developer.android.google.cn/static/images/training/lint.png?authuser=9&hl=ru)
Lint может автоматически устранять некоторые проблемы, предлагать решения по другим и сразу переходить к проблемному коду для проверки.
Дополнительные сведения см. в разделе Макеты и ресурс макета .