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

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

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

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

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

Чтобы увидеть различные макеты, которые можно создать с помощью ConstraintLayout , см. проект Constraint LayoutExamples на 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 > «Layout XML» .
  2. Введите имя файла макета и введите «androidx.constraintlayout.widget.ConstraintLayout» в качестве корневого тега .
  3. Нажмите «Готово» .

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Видео 3. Настройка смещения ограничения.

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

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

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

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

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

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

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

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

    • layout_constraintWidth_max

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

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

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

Рисунок 15. Для просмотра установлено соотношение сторон 16:9, а ширина зависит от соотношения высоты.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Представление «голова» цепочки — самое левое представление в горизонтальной цепочке (в макете слева направо) и самое верхнее представление в вертикальной цепочке — определяет стиль цепочки в XML. Однако вы можете переключаться между разворотом , разворотом внутри и упаковкой , выбрав любое представление в цепочке и нажав кнопку цепочки. который появляется под видом.

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

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

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

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

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

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

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

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

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

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

Ключевые кадры анимации

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