Что реализовать: ConstraintLayout
или CoordinatorLayout
для правильного дизайна материалов в Android?
ConstraintLayout против макета координатора?
Ответы (4)
CoordinatorLayout — это мощный FrameLayout.
CoordinatorLayout
предназначен для двух основных вариантов использования:
- Как декор приложения верхнего уровня или хром-макет
- Как контейнер для определенного взаимодействия с одним или несколькими дочерними представлениями
По умолчанию, если вы добавите несколько дочерних элементов в FrameLayout
, они будут перекрывать друг друга. FrameLayout
чаще всего следует использовать для хранения одного дочернего представления. Основная привлекательность CoordinatorLayout
заключается в его способности координировать анимацию и переходы представлений внутри него. Указав Поведения для дочерних представлений CoordinatorLayout
, вы можете обеспечивают множество различных взаимодействий внутри одного родителя, и эти представления также могут взаимодействовать друг с другом. Классы представления могут указывать поведение по умолчанию при использовании в качестве дочернего элемента CoordinatorLayout
с использованием аннотации CoordinatorLayout.DefaultBehavior
.
Поведения могут использоваться для реализации различных взаимодействий и дополнительных модификаций макета, начиная от выдвижных ящиков и панелей и заканчивая элементами, которые можно закрыть смахиванием, и кнопками, которые прикрепляются к другим элементам по мере их перемещения и анимации.
ConstraintLayout — это мощная ViewGroup, похожая на RelativeLayout, но более гибкая, чем RelativeLayout.
ConstraintLayout
позволяет создавать большие и сложные макеты с плоской иерархией представлений (без вложенных групп представлений). Он похож на RelativeLayout тем, что все представления располагаются в соответствии с отношениями между одноуровневыми представлениями и родительским макетом, но он более гибкий, чем RelativeLayout
, и его проще использовать с редактором макетов Android Studio.
ConstraintLayout
можно использовать где угодно, вам не нужны никакие другие ViewGroup, такие какRelativeLayout
,LinearLayout
илиFrameLayout
, как только вы начнете использоватьConstraintLayout
.
В настоящее время существуют различные типы ограничений, которые вы можете использовать:
- Относительное позиционирование
- Поля
- Центрирование позиционирования
- Круговое позиционирование
- Поведение видимости
- Ограничения размеров
- Цепи
- Объекты виртуальных помощников
- Оптимизатор
Что реализовать: ConstraintLayout
или CoordinatorLayout
для правильного дизайна материалов в Android?
Возможно, вам придется использовать как ConstraintLayout
, так и CoordinatorLayout
для создания эффективного пользовательского интерфейса и анимации материалов.
Типичный пример, в котором используются как CoordinatorLayout
, так и ConstraintLayout
, приведен ниже для справки.
Используйте
Coordinatorlayout
в качестве оформления приложения верхнего уровня. Обычно он используется для макетаAppBarLayout
,FloatingActionButton
и основной части экрана, скажем,NestedScrollView
. ВнутриNestedScrollView
используйтеConstraintLayout
, чтобы описать остальную часть макета как плоскую иерархию.<androidx.coordinatorlayout.widget.CoordinatorLayout 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"> <androidx.core.widget.NestedScrollView android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"> <!-- Your scrolling content --> <androidx.constraintlayout.widget.ConstraintLayout ...> <!-- body of constraint layout --> <Button android:id="@+id/button" ... app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent/> </androidx.constraintlayout.widget.ConstraintLayout> </androidx.core.widget.NestedScrollView> <com.google.android.material.appbar.AppBarLayout android:layout_height="wrap_content" android:layout_width="match_parent"> <androidx.appcompat.widget.Toolbar ... app:layout_scrollFlags="scroll|enterAlways"/> <com.google.android.material.tabs.TabLayout ... app:layout_scrollFlags="scroll|enterAlways"/> </com.google.android.material.appbar.AppBarLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>
Что означает приведенный выше фрагмент? вот так.
- Мы разместили
androidx.coordinatorlayout.widget.CoordinatorLayout
в качестве корневого макета. И ставимandroidx.core.widget.NestedScrollView
иcom.google.android.material.appbar.AppBarLayout
прямыми дочерними. Мы определили атрибут
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
дляandroidx.core.widget.NestedScrollView
. Это ключевой момент. Мы определили поведение для файлаNestedScrollView
. То есть мы сообщаем макету координатора, чтоNestedScrollView
зависит отAppBarLayout
.- Of course, Behaviors don’t do anything on their own, but CoordinatorLayout does. It act accordingly and helps to intercept touch events, window insets, measurement, layout, and nested scrolling. So here, it places the NestedScrollView below the AppBarLayout as we instructed. Cool right?
Мы поместили
ConstraintLayout
внутриNestedScrollView
, чтобы его можно было прокручивать. Как мы уже говорили, ConstraintLayout используется для выравнивания дочерних представлений с границами ConstraintLayout.
Можно ли добавить ConstraintLayout внутрь другого ConstraintLayout?
Конечно да, вы можете использовать любую комбинацию для выравнивания представлений в соответствии с вашими требованиями к дизайну.
Можно ли добавить CoordinatorLayout внутрь другого CoordinatorLayout?
Это не обычная практика. наиболее распространенный вариант использования CoordinatorLayout — это оформление приложения верхнего уровня для координации между другими прямыми дочерними элементами. Но да, если вы действительно хотите вложить CoordinatorLayout, вы можете сделать это, создав собственный CoordinatorLayout, который расширяет CoordinatorLayout
и реализует NestedScrollingChild
для передачи событий прокрутки родительскому CoordinatorLayout.
Бонусный балл
Вы можете использовать мощный MotionLayout, который является подклассом ConstraintLayout
для анимация построения. Вы можете просмотреть здесь подробный пример пользовательской анимации с использованием MotionLayout
.
CoordinatorLayout предназначен для использования в качестве макета верхнего уровня для действий по управлению Поведение, например. взаимодействия и анимации.
Основная цель ConstraintLayout — предоставить удобный способ создания плоского макета с несколькими дочерними элементами (гораздо более мощный RelativeLayout).
Таким образом, CoordinatorLayout предназначен для управления сложным поведением (особенно анимацией) компонентов вашей активности, а ConstraintLayout — для правильного размещения компонентов (особенно элементов списка).
Похоже, вы (почти) всегда используете CoordinatorLayout
, а иногда используете ConstraintLayout
внутри. См. следующие ресурсы
Лаборатория кода по адресу https://codelabs.developers.google.com/codelabs/material-design-style/index.html#3 использует только
CoordinatorLayout
Пример приложения android-sunflower («иллюстрация лучших практик разработки Android») не использует ни то, ни другое для активности верхнего уровня, но использует оба внутри своего
fragment_plant_detail.xml
, гдеConstraintLayout
находится внутриCoordinatorLayout
:<layout ...> <data .../> <android.support.design.widget.CoordinatorLayout ...> <android.support.design.widget.AppBarLayout ...> <android.support.design.widget.CollapsingToolbarLayout ...> <ImageView... /> <android.support.v7.widget.Toolbar... /> </android.support.design.widget.CollapsingToolbarLayout> </android.support.design.widget.AppBarLayout> <android.support.v4.widget.NestedScrollView ...> <android.support.constraint.ConstraintLayout ...> <TextView.../> <TextView... /> </android.support.constraint.ConstraintLayout> </android.support.v4.widget.NestedScrollView> <android.support.design.widget.FloatingActionButton ... /> </android.support.design.widget.CoordinatorLayout> </layout>
У @Darish есть отличный исчерпывающий ответ на этот вопрос. Я поддерживаю все, что он сказал, и хотел просто добавить немного информации. По моему опыту, макет Constraint в качестве родительского представления достаточно хорош в большинстве случаев. Когда вам нужно ввести макет координатора, это когда у вас есть определенные поведения, которыми вы хотите управлять (например, нижние листы). С Coordinator Layout больше проблем, чем того стоит, если вы не будете использовать его возможности поведения или если вы пытаетесь возиться с несколькими представлениями, поскольку CoordinatorLayout действует как «сверхмощный FrameLayout».
Некоторое время назад я написал сообщение в блоге с иллюстрациями о различиях и использовании макета Coordinator и Constraint. Проверьте это здесь, если вам интересно.
Я также хотел бы добавить плагин для MotionLayout как отличный способ добавить анимацию в ваши макеты без большого количества дополнительного кода! Эта серия для разработчиков Google с примерами — отличный способ чтобы начать работу с MotionLayout.