Создайте адаптивный пользовательский интерфейс с помощью ConstraintLayout , части Android Jetpack .

Попробуйте способ Compose
Jetpack Compose — рекомендуемый набор инструментов пользовательского интерфейса для Android. Узнайте, как работать с макетами в Compose.

ConstraintLayout позволяет создавать большие, сложные макеты с плоской иерархией представлений — без вложенных групп представлений. Он похож на RelativeLayout в том, что все представления располагаются в соответствии с отношениями между одноуровневыми представлениями и родительским макетом, но он более гибок, чем RelativeLayout , и его проще использовать с редактором макетов Android Studio.

Вся мощь ConstraintLayout доступна непосредственно из визуальных инструментов редактора макетов, поскольку API макета и редактор макетов специально созданы друг для друга. Вы можете создать свой макет с помощью ConstraintLayout полностью перетаскиванием, а не редактированием XML.

На этой странице показано, как создать макет с помощью ConstraintLayout в Android Studio 3.0 или выше. Для получения дополнительной информации о редакторе макетов см. раздел Создание пользовательского интерфейса с помощью редактора макетов .

Чтобы увидеть различные макеты, которые можно создать с помощью ConstraintLayout , ознакомьтесь с проектом Constraint Layout Examples на GitHub .

Обзор ограничений

Чтобы определить положение представления в ConstraintLayout , вы добавляете по крайней мере одно горизонтальное и одно вертикальное ограничение для представления. Каждое ограничение представляет собой соединение или выравнивание с другим представлением, родительским макетом или невидимой направляющей. Каждое ограничение определяет положение представления вдоль вертикальной или горизонтальной оси. Каждое представление должно иметь как минимум одно ограничение для каждой оси, но часто требуется больше.

Когда вы перетаскиваете вид в редактор макетов, он остается там, где вы его оставили, даже если у него нет ограничений. Это сделано только для того, чтобы упростить редактирование. Если вид не имеет ограничений при запуске макета на устройстве, он рисуется в позиции [0,0] (верхний левый угол).

На рисунке 1 макет выглядит хорошо в редакторе, но для вида C нет вертикальных ограничений. Когда этот макет отображается на устройстве, вид C горизонтально выравнивается по левому и правому краям вида A, но он отображается в верхней части экрана, поскольку у него нет вертикальных ограничений.

Рисунок 1. Редактор показывает вид C под A, но он не имеет вертикальных ограничений.

Рисунок 2. Вид C теперь вертикально ограничен видом A.

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

Добавьте ConstraintLayout в свой проект

Чтобы использовать ConstraintLayout в своем проекте, выполните следующие действия:

  1. Убедитесь, что в файле settings.gradle объявлен репозиторий maven.google.com :

    Круто

        dependencyResolutionManagement {
          ...
          repositories {
              google()
          }
        )
        

    Котлин

        dependencyResolutionManagement {
          ...
          repositories {
              google()
          }
        }
        
  2. Добавьте библиотеку как зависимость в файл build.gradle на уровне модуля, как показано в следующем примере. Последняя версия может отличаться от той, что показана в примере.

    классный

    dependencies {
        implementation "androidx.constraintlayout:constraintlayout:2.2.0-beta01"
        // To use constraintlayout in compose
        implementation "androidx.constraintlayout:constraintlayout-compose:1.1.0-beta01"
    }

    Котлин

    dependencies {
        implementation("androidx.constraintlayout:constraintlayout:2.2.0-beta01")
        // To use constraintlayout in compose
        implementation("androidx.constraintlayout:constraintlayout-compose:1.1.0-beta01")
    }
  3. На панели инструментов или в уведомлении о синхронизации нажмите Синхронизировать проект с файлами Gradle .

Теперь вы готовы создать свой макет с помощью ConstraintLayout .

Преобразовать макет

Рисунок 3. Меню для преобразования макета в ConstraintLayout .

Чтобы преобразовать существующий макет в макет ограничений, выполните следующие действия:

  1. Откройте макет в Android Studio и щелкните вкладку «Дизайн» в нижней части окна редактора.
  2. В окне «Дерево компонентов» щелкните правой кнопкой мыши макет и выберите команду «Преобразовать LinearLayout в ConstraintLayout» .

Создать новый макет

Чтобы создать новый файл макета ограничений, выполните следующие действия:

  1. В окне проекта щелкните папку модуля и выберите Файл > Создать > XML > Макет XML .
  2. Введите имя файла макета и введите «androidx.constraintlayout.widget.ConstraintLayout» для корневого тега .
  3. Нажмите «Готово» .

Добавить или удалить ограничение

Чтобы добавить ограничение, выполните следующие действия:

Видео 1. Левая сторона представления ограничена левой стороной родителя.

  1. Перетащите вид из окна палитры в редактор.

    При добавлении представления в ConstraintLayout оно отображается в ограничивающей рамке с квадратными маркерами изменения размера на каждом углу и круглыми маркерами ограничений на каждой стороне.

  2. Щелкните вид, чтобы выбрать его.
  3. Выполните одно из следующих действий:
    • Щелкните маркер ограничения и перетащите его в доступную точку привязки. Эта точка может быть краем другого вида, краем макета или направляющей. Обратите внимание, что при перетаскивании маркера ограничения редактор макета показывает потенциальные якоря соединения и синие наложения.
    • Нажмите одну из кнопок «Создать соединение». кнопки в разделе «Макет» окна «Атрибуты» , как показано на рисунке 4.

      Рисунок 4. Раздел «Макет» окна «Атрибуты» позволяет создавать соединения.

При создании ограничения редактор задает ему поле по умолчанию для разделения двух представлений.

При создании ограничений помните следующие правила:

  • Каждое представление должно иметь как минимум два ограничения: одно горизонтальное и одно вертикальное.
  • Вы можете создавать ограничения только между ручкой ограничения и точкой привязки, которые разделяют одну и ту же плоскость. Вертикальная плоскость — левая и правая стороны — вида может быть ограничена только другой вертикальной плоскостью, а базовые линии могут ограничивать только другие базовые линии.
  • Каждый маркер ограничения может использоваться только для одного ограничения, но можно создать несколько ограничений из разных видов для одной и той же точки привязки.

Вы можете удалить ограничение, выполнив любое из следующих действий:

  • Щелкните ограничение, чтобы выбрать его, а затем щелкните Удалить .
  • Control -клик ( Command -клик на macOS) на якоре ограничения. Ограничение становится красным, что означает, что вы можете щелкнуть, чтобы удалить его, как показано на рисунке 5.

    Рисунок 5. Красное ограничение указывает на то, что вы можете щелкнуть, чтобы удалить его.

  • В разделе «Макет» окна «Атрибуты» щелкните якорь ограничения, как показано на рисунке 6.

    Рисунок 6. Щелкните якорь ограничения, чтобы удалить его.

Видео 2. Добавление ограничения, противостоящего существующему.

Если вы добавляете противоположные ограничения к представлению, линии ограничений скручиваются как пружина, чтобы указать на противодействующие силы, как показано в видео 2. Эффект наиболее заметен, когда размер представления установлен на «фиксированный» или «обернуть содержимое», в этом случае представление центрируется между ограничениями. Если вместо этого вы хотите, чтобы представление растягивалось в соответствии с ограничениями, переключите размер на «соответствовать ограничениям». Если вы хотите сохранить текущий размер, но переместить представление так, чтобы оно не было центрировано, отрегулируйте смещение ограничения .

Вы можете использовать ограничения для достижения различных типов поведения макета, как описано в следующих разделах.

Родительская позиция

Ограничьте сторону вида соответствующим краем макета.

На рисунке 7 левая сторона представления соединена с левым краем родительского макета. Вы можете определить расстояние от края с помощью margin.

Рисунок 7. Горизонтальное ограничение родительского объекта.

Позиция заказа

Определите порядок отображения двух видов: по вертикали или по горизонтали.

На рисунке 8 точка B ограничена тем, что всегда находится справа от A, а точка C ограничена тем, что находится ниже A. Однако эти ограничения не подразумевают выравнивания, поэтому точка B по-прежнему может перемещаться вверх и вниз.

Рисунок 8. Горизонтальное и вертикальное ограничение.

Выравнивание

Выровняйте край вида по такому же краю другого вида.

На рисунке 9 левая сторона B выровнена с левой стороной A. Если вы хотите выровнять центры видов, создайте ограничение с обеих сторон.

Вы можете сместить выравнивание, перетащив вид внутрь от ограничения. Например, на рисунке 10 показан B с выравниванием смещения 24dp. Смещение определяется полями ограниченного вида.

Вы также можете выбрать все виды, которые хотите выровнять, а затем нажать «Выровнять». на панели инструментов, чтобы выбрать тип выравнивания.

Рисунок 9. Ограничение горизонтального выравнивания.

Рисунок 10. Ограничение горизонтального выравнивания со смещением.

Выравнивание базовой линии

Выровняйте базовую линию текста одного представления с базовой линией текста другого представления.

На рисунке 11 первая строка B выровнена с текстом A.

Чтобы создать ограничение базовой линии, щелкните правой кнопкой мыши текстовое представление, которое вы хотите ограничить, а затем щелкните Показать базовую линию . Затем щелкните базовую линию текста и перетащите линию на другую базовую линию.

Рисунок 11. Ограничение выравнивания базовой линии.

Ограничить руководящие принципы

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

Чтобы создать руководство, нажмите «Руководства» . на панели инструментов, а затем нажмите Добавить вертикальную направляющую или Добавить горизонтальную направляющую .

Перетащите пунктирную линию, чтобы изменить ее положение, и щелкните кружок на краю направляющей, чтобы переключить режим измерения.

Рисунок 12. Вид, ограниченный направляющей линией.

Ограничить барьером

Подобно направляющей, барьер — это невидимая линия, которой можно ограничить представления, за исключением того, что барьер не определяет свое собственное положение. Вместо этого положение барьера перемещается в зависимости от положения представлений, содержащихся в нем. Это полезно, когда вы хотите ограничить представление набором представлений, а не одним конкретным представлением.

Например, на рисунке 13 вид C ограничен правой стороной барьера. Барьер установлен в «конце» (или правой стороне, в макете слева направо) как вида A, так и вида B. Барьер перемещается в зависимости от того, является ли правая сторона вида A или вида B самой правой.

Чтобы создать барьер, выполните следующие действия:

  1. Нажмите «Руководство» на панели инструментов, а затем нажмите Добавить вертикальный барьер или Добавить горизонтальный барьер .
  2. В окне «Дерево компонентов» выберите нужные представления внутри барьера и перетащите их в компонент барьера.
  3. Выберите барьер из дерева компонентов , откройте атрибуты. окно, а затем установите barrierDirection .

Теперь вы можете создать ограничение из другого вида на барьер.

Вы также можете ограничить виды, которые находятся внутри барьера, барьером. Таким образом, вы можете выровнять все виды в барьере друг с другом, даже если вы не знаете, какой вид самый длинный или самый высокий.

Вы также можете включить направляющую линию внутрь ограждения, чтобы обеспечить «минимальное» положение ограждения.

Рисунок 13. Вид C ограничен барьером, который перемещается в зависимости от положения и размера как вида A, так и вида B.

Отрегулируйте смещение ограничения

Когда вы добавляете ограничение к обеим сторонам представления, а размер представления для того же измерения либо «фиксированный», либо «перенос содержимого», представление становится центрированным между двумя ограничениями со смещением 50% по умолчанию. Вы можете настроить смещение, перетащив ползунок смещения в окне Атрибуты или перетащив представление, как показано в видео 3.

Если вместо этого вы хотите, чтобы размер представления был увеличен в соответствии с ограничениями, измените размер на «соответствовать ограничениям».

Видео 3. Регулировка смещения ограничения.

Настройте размер представления

Рисунок 14. При выборе представления окно атрибутов включает элементы управления для 1 соотношения размеров, 2 удаления ограничений, 3 режима высоты или ширины, 4 полей и 5 смещения ограничений. Вы также можете выделить отдельные ограничения в редакторе макетов, щелкнув их в списке 6 ограничений.

Вы можете использовать угловые маркеры для изменения размера представления, но это жестко закодирует размер — представление не меняет размер для разного контента или размеров экрана. Чтобы выбрать другой режим размера, щелкните представление и откройте Атрибуты окно в правой части редактора.

В верхней части окна «Атрибуты» находится инспектор представлений, который включает элементы управления несколькими атрибутами макета, как показано на рисунке 14. Он доступен только для представлений в макете ограничений.

Вы можете изменить способ расчета высоты и ширины, нажав на символы, обозначенные выноской 3 на рисунке 14. Эти символы представляют режим размера следующим образом. Щелкните на символе, чтобы переключиться между этими настройками:

  • Исправлено : укажите конкретное измерение в следующем текстовом поле или изменив размер представления в редакторе.
  • Обертывание содержимого : представление расширяется ровно настолько, насколько это необходимо для размещения его содержимого.
    • layout_constrainedWidth
    • Установите это значение в true , чтобы горизонтальное измерение изменялось в соответствии с ограничениями. По умолчанию виджет, установленный в WRAP_CONTENT , не ограничен ограничениями.

  • Соответствие ограничениям : представление расширяется настолько, насколько это возможно, чтобы соответствовать ограничениям с каждой стороны, после учета полей представления. Однако вы можете изменить это поведение с помощью следующих атрибутов и значений. Эти атрибуты вступают в силу только тогда, когда вы устанавливаете ширину представления на «соответствие ограничениям»:
    • layout_constraintWidth_min

      Для минимальной ширины представления используется размер dp .

    • layout_constraintWidth_max

      Для максимальной ширины представления используется измерение dp .

    Однако если заданное измерение имеет только одно ограничение, то представление расширяется, чтобы вместить его содержимое. Использование этого режима как по высоте, так и по ширине также позволяет вам задать соотношение размеров .

Установить размер как соотношение

Рисунок 15. Вид настроен на соотношение сторон 16:9, ширина которого основана на соотношении высоты.

Вы можете задать размер представления в соотношении, например 16:9, если хотя бы одно из измерений представления установлено на «соответствие ограничениям» ( 0dp ). Чтобы включить соотношение, щелкните Переключить ограничение соотношения сторон (выноска 1 на рисунке 14) и введите соотношение width и height в появившемся поле ввода.

Если и ширина, и высота установлены на "соответствие ограничениям", вы можете нажать Toggle Aspect Ratio Constraint, чтобы выбрать, какое измерение основано на соотношении другого. Инспектор видов указывает, какое измерение установлено как соотношение, соединяя соответствующие края сплошной линией.

Например, если вы установите обе стороны на "соответствие ограничениям", дважды щелкните Toggle Aspect Ratio Constraint, чтобы установить ширину как отношение высоты. Весь размер диктуется высотой представления, которая может быть определена любым способом, как показано на рисунке 15.

Отрегулируйте поля просмотра

Чтобы сделать ваши представления равномерно распределенными, нажмите «Марж». на панели инструментов, чтобы выбрать поле по умолчанию для каждого представления, которое вы добавляете в макет. Любое изменение поля по умолчанию, которое вы вносите, применяется только к представлениям, которые вы добавляете с этого момента.

Вы можете управлять полем для каждого представления в окне Атрибуты , нажав на число в строке, представляющей каждое ограничение. На рисунке 14 выноска 4 показывает, что нижнее поле установлено на 16dp.

Рисунок 16. Кнопка «Поля» на панели инструментов.

Все поля, предлагаемые инструментом, имеют коэффициент 8dp, что помогает вашим представлениям соответствовать рекомендациям Material Design по квадратной сетке 8dp.

Управляйте линейными группами с помощью цепи

Рисунок 17. Горизонтальная цепь с двумя видами.

Цепочка — это группа представлений, связанных друг с другом двунаправленными ограничениями положения. Представления внутри цепочки могут быть распределены как вертикально, так и горизонтально.

Рисунок 18. Примеры каждого стиля цепи.

Цепи можно оформить одним из следующих способов:

  1. Spread: просмотры распределяются равномерно после учета маржи. Это значение по умолчанию.
  2. Распределение внутри: первое и последнее представления прикреплены к ограничениям на каждом конце цепи, а остальные распределены равномерно.
  3. Weighted: когда цепочка установлена ​​на spread или spread inside , вы можете заполнить оставшееся пространство, установив для одного или нескольких представлений значение «match constraints» ( 0dp ). По умолчанию пространство равномерно распределяется между каждым представлением, для которого установлено значение «match constraints», но вы можете назначить вес важности для каждого представления с помощью атрибутов layout_constraintHorizontal_weight и layout_constraintVertical_weight . Это работает так же, как layout_weight в линейном макете : представление с наибольшим значением веса получает больше всего пространства, а представления с таким же весом получают одинаковое количество пространства.
  4. Упаковано: представления упакованы вместе после учета полей. Вы можете настроить смещение всей цепочки — влево или вправо, вверх или вниз — изменив смещение представления «головы» цепочки.

Вид "головы" цепочки — самый левый вид в горизонтальной цепочке (в макете слева направо) и самый верхний вид в вертикальной цепочке — определяет стиль цепочки в XML. Однако вы можете переключаться между spread , spread inside и packed , выбрав любой вид в цепочке и нажав кнопку chain который отображается под видом.

Чтобы создать цепочку, выполните следующие действия, как показано в видео 4:

  1. Выберите все представления, которые необходимо включить в цепочку.
  2. Щелкните правой кнопкой мыши по одному из представлений.
  3. Выберите Цепи .
  4. Выберите Центрировать по горизонтали или Центрировать по вертикали .

Видео 4. Создание горизонтальной цепи.

Вот несколько моментов, которые следует учитывать при использовании цепей:

  • Представление может быть частью как горизонтальной, так и вертикальной цепочки, что позволяет создавать гибкие сеточные макеты.
  • Цепь работает правильно только в том случае, если каждый ее конец ограничен другим объектом на той же оси, как показано на рисунке 14.
  • Хотя ориентация цепочки может быть вертикальной или горизонтальной, ее использование не выравнивает представления в этом направлении. Чтобы добиться правильного положения для каждого представления в цепочке, включите другие ограничения, такие как ограничения выравнивания .

Автоматически создавать ограничения

Вместо того чтобы добавлять ограничения к каждому представлению при их размещении в макете, вы можете переместить каждое представление в нужные вам позиции в редакторе макетов, а затем нажать «Вывести ограничения». для автоматического создания ограничений.

Infer Constraints сканирует макет, чтобы определить наиболее эффективный набор ограничений для всех представлений. Он ограничивает представления их текущими позициями, обеспечивая гибкость. Вам может потребоваться внести изменения, чтобы макет реагировал так, как вы предполагаете, на различные размеры экрана и ориентации.

Autoconnect to Parent — это отдельная функция, которую вы можете включить. Когда она включена и вы добавляете дочерние представления к родительскому, эта функция автоматически создает два или более ограничений для каждого представления по мере их добавления в макет, но только когда целесообразно ограничить представление родительским макетом. Autoconnect не создает ограничений для других представлений в макете.

Автоподключение отключено по умолчанию. Включите его, нажав Включить автоподключение к родительскому элементу на панели инструментов редактора макетов.

Анимация ключевых кадров

В ConstraintLayout вы можете анимировать изменения размера и положения элементов, используя ConstraintSet и TransitionManager .

ConstraintSet — это легкий объект, который представляет ограничения, поля и отступы всех дочерних элементов в ConstraintLayout . Когда вы применяете ConstraintSet к отображаемому ConstraintLayout , макет обновляет ограничения всех своих дочерних элементов.

Чтобы создать анимацию с помощью ConstraintSet , укажите два файла макета, которые будут выступать в качестве начального и конечного ключевых кадров для анимации. Затем вы можете загрузить ConstraintSet из второго файла ключевого кадра и применить его к отображаемому ConstraintLayout .

В следующем примере кода показано, как анимировать перемещение одной кнопки в нижнюю часть экрана.

// MainActivity.kt

fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.keyframe_one)
    constraintLayout = findViewById(R.id.constraint_layout) // member variable
}

fun animateToKeyframeTwo() {
    val constraintSet = ConstraintSet()
    constraintSet.load(this, R.layout.keyframe_two)
    TransitionManager.beginDelayedTransition()
    constraintSet.applyTo(constraintLayout)
}
// layout/keyframe1.xml
// Keyframe 1 contains the starting position for all elements in the animation
// as well as final colors and text sizes.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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">

    <Button
        android:id="@+id/button2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Button"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
// layout/keyframe2.xml
// Keyframe 2 contains another ConstraintLayout with the final positions.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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">

    <Button
        android:id="@+id/button2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Button"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintBottom_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

Дополнительные ресурсы

ConstraintLayout используется в демонстрационном приложении Sunflower .