В Compose можно объединять несколько модификаторов, чтобы изменять внешний вид и функциональность составного объекта. Эти цепочки модификаторов могут влиять на ограничения, передаваемые составным объектам, которые определяют границы ширины и высоты.
На этой странице описывается, как связанные между собой модификаторы влияют на ограничения и, в свою очередь, на измерение и размещение композиционных элементов.
Модификаторы в дереве пользовательского интерфейса
Чтобы понять, как модификаторы влияют друг на друга, полезно визуализировать их отображение в дереве пользовательского интерфейса, которое генерируется на этапе композиции. Для получения дополнительной информации см. раздел «Композиция» .
В древовидной структуре пользовательского интерфейса модификаторы можно визуализировать как узлы-оболочки для узлов компоновки:

Добавление более одного модификатора к составному элементу создает цепочку модификаторов. При объединении нескольких модификаторов каждый узел модификатора инкапсулирует остальную часть цепочки и узел компоновки . Например, при объединении модификатора clip и модификатора size узел модификатора clip инкапсулирует узел модификатора size , который затем инкапсулирует узел компоновки Image .
На этапе компоновки алгоритм обхода дерева остается тем же, но при этом посещается каждый узел-модификатор. Таким образом, модификатор может изменять требования к размеру и расположение узла-модификатора или узла компоновки, который он оборачивает.
Как показано на рисунке 2, реализация самих составных элементов Image и Text представляет собой цепочку модификаторов, охватывающих один узел компоновки.
Объекты Row и Column представляют собой узлы компоновки, описывающие, как размещать дочерние элементы.

В заключение:
- Модификаторы представляют собой обертки для одного модификатора или узла компоновки.
- Узлы компоновки могут размещать несколько дочерних узлов.
В следующих разделах описывается, как использовать эту ментальную модель для рассуждений о цепочках модификаторов и о том, как она влияет на размер составных элементов.
Ограничения на этапе компоновки.
На этапе компоновки используется трехэтапный алгоритм для определения ширины, высоты и координат x, y каждого узла компоновки:
- Измерение дочерних узлов : узел измеряет количество своих дочерних узлов, если таковые имеются.
- Определение собственного размера : На основе этих измерений узел определяет свой собственный размер.
- Размещение дочерних узлов : Каждый дочерний узел размещается относительно собственного положения узла.
Constraints помогают определить правильные размеры узлов на первых двух этапах алгоритма. Ограничения определяют минимальные и максимальные границы ширины и высоты узла. Когда узел определяет свой размер, измеренный размер должен попадать в этот диапазон.
Типы ограничений
Ограничение может быть одним из следующих:
- Ограничения : Узел имеет максимальную и минимальную ширину и высоту.

- Без ограничений : размер узла не ограничен никакими параметрами. Максимальная ширина и высота установлены на бесконечность.

- Точное значение : Узлу задается точное требование к размеру. Минимальный и максимальный пределы устанавливаются на одно и то же значение.

- Комбинация : Узел соответствует комбинации описанных выше типов ограничений. Например, ограничение может ограничивать ширину, допуская при этом неограниченную максимальную высоту, или задавать точную ширину, но ограничивать высоту.

В следующем разделе описывается, как эти ограничения передаются от родителя к потомку.
Как ограничения передаются от родителя к ребенку
На первом этапе алгоритма, описанного в разделе «Ограничения на этапе компоновки» , ограничения передаются от родительского элемента к дочернему в дереве пользовательского интерфейса.
Когда родительский узел измеряет размеры своих дочерних узлов, он передает эти ограничения каждому дочернему узлу, чтобы сообщить им, насколько большими или маленькими они могут быть. Затем, при определении собственного размера, он также придерживается ограничений, переданных его собственными родителями.
В общих чертах алгоритм работает следующим образом:
- Чтобы определить фактический размер, который он хочет занять, корневой узел в дереве пользовательского интерфейса измеряет свои дочерние элементы и передает те же ограничения своему первому дочернему элементу.
- Если дочерний модификатор не влияет на измерение, он передает ограничения следующему модификатору. Ограничения передаются по цепочке модификаторов как есть, если только не встречается модификатор, влияющий на измерение. В этом случае ограничения изменяются в соответствии с заданными параметрами.
- Как только достигается узел, не имеющий дочерних элементов (называемый «листовым узлом»), он определяет свой размер на основе переданных ограничений и возвращает этот определенный размер своему родительскому узлу.
- Родительский процесс корректирует свои ограничения на основе измерений дочернего процесса и вызывает следующий дочерний процесс с этими скорректированными ограничениями.
- После того как размеры всех дочерних узлов родительского узла будут измерены, родительский узел определяет свой собственный размер и сообщает об этом своему родительскому узлу.
- Таким образом, дерево обходится в глубину. В конечном итоге, все узлы определяют свои размеры, и этап измерения завершается.
Для более подробного примера посмотрите видеоролик «Ограничения и порядок модификаторов» .
Модификаторы, влияющие на ограничения
В предыдущем разделе вы узнали, что некоторые модификаторы могут влиять на размер ограничений. В следующих разделах описаны конкретные модификаторы, влияющие на ограничения.
Модификатор size
Модификатор size определяет предпочтительный размер содержимого.
Например, следующее дерево элементов пользовательского интерфейса должно отображаться в контейнере размером 300dp на 200dp . Ограничения являются граничными, допуская ширину от 100dp до 300dp и высоту от 100dp до 200dp :

Модификатор size адаптирует входящие ограничения в соответствии с переданным ему значением. В этом примере значение равно 150dp :

size , корректирующий ограничения до 150dp .Если ширина и высота меньше наименьшего ограничения или больше наибольшего ограничения, модификатор максимально точно соответствует переданным ограничениям, при этом соблюдая заданные ограничения:

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

size , в которой второе переданное значение ( 50dp ) не переопределяет первое значение ( 100dp ).Модификатор requiredSize
Используйте модификатор requiredSize вместо size , если вам нужно, чтобы ваш узел переопределял входящие ограничения. Модификатор requiredSize заменяет входящие ограничения и передает указанный вами размер в качестве точных границ.
Когда размер передается обратно вверх по дереву, дочерний узел будет центрирован в доступном пространстве:

requiredSize , переопределяющий входящие ограничения из модификатора size . Модификаторы width и height
Модификатор size изменяет как ширину, так и высоту ограничений. С помощью модификатора width можно задать фиксированную ширину, но оставить высоту неопределенной. Аналогично, с помощью модификатора height можно задать фиксированную высоту, но оставить ширину неопределенной.

width и модификатор height , задающие фиксированную ширину и высоту соответственно. Модификатор sizeIn
Модификатор sizeIn позволяет задать точные минимальные и максимальные значения ширины и высоты. Используйте модификатор sizeIn если вам необходим более точный контроль над ограничениями.

sizeIn с заданными значениями minWidth , maxWidth , minHeight и maxHeight .Примеры
В этом разделе показаны и объяснены результаты выполнения нескольких фрагментов кода с цепочками модификаторов.
Image( painterResource(R.drawable.hero), contentDescription = null, Modifier .fillMaxSize() .size(50.dp) )
Этот фрагмент кода выдает следующий результат:

Image заполняет максимальный размер в результате применения цепочки модификаторов.- Модификатор
fillMaxSizeизменяет ограничения, устанавливая минимальную ширину и высоту на максимальные значения —300dpпо ширине и200dpпо высоте. - Даже если модификатор
sizeхочет использовать размер50dp, он все равно должен соблюдать входящие минимальные ограничения. Поэтому модификаторsizeтакже выдаст точные границы ограничения300на200, фактически игнорируя значение, указанное в модификатореsize. -
Imageсоответствует этим границам и имеет размер300на200, который передается по всей структуре дерева.
Image( painterResource(R.drawable.hero), contentDescription = null, Modifier .fillMaxSize() .wrapContentSize() .size(50.dp) )
Этот фрагмент кода выдает следующий результат:

Image центрировано и имеет размер 50dp .- Модификатор
fillMaxSizeадаптирует ограничения, устанавливая минимальную ширину и высоту на максимальное значение —300dpпо ширине и200dpпо высоте. - Модификатор
wrapContentSizeсбрасывает минимальные ограничения. Таким образом, еслиfillMaxSizeприводил к фиксированным ограничениям, тоwrapContentSizeвозвращает их к ограниченным . Следующий узел теперь может снова занимать все пространство или быть меньше всего пространства. - Модификатор
sizeустанавливает ограничения на минимальное и максимальное значения, равные50. -
Imageимеет размер50на50, и модификаторsizeпередает это значение дальше. - Модификатор
wrapContentSizeобладает особым свойством. Он помещает свой дочерний элемент в центр минимальных доступных границ , которые были ему переданы. Таким образом, размер, который он сообщает своим родительским элементам, равен минимальным границам, переданным ему.
Комбинируя всего три модификатора, вы можете задать размер для составного элемента и центрировать его относительно родительского элемента.
Image( painterResource(R.drawable.hero), contentDescription = null, Modifier .clip(CircleShape) .padding(10.dp) .size(100.dp) )
Этот фрагмент кода выдает следующий результат:

- Модификатор
clipне изменяет ограничения. - Модификатор
paddingуменьшает максимальные ограничения. - Модификатор
sizeустанавливает все ограничения на100dp. -
Imageсоответствует этим ограничениям и имеет размер100dpна100dp. - Модификатор
paddingдобавляет10dpсо всех сторон к размеру, указанному элементомImage, поэтому макет с padding отображает ширину и высоту120dp. - Теперь, на этапе рисования, модификатор
clipвоздействует на холст размером120dpна120dp. Он создает маску в виде круга такого размера. - Модификатор
paddingзатем вставляет содержимое на10dpсо всех сторон, что уменьшает размер холста дляImageдо100dpна100dp. -
Imageрисуется на этом меньшем холсте. Изображение обрезается относительно исходного круга размером120dp, поэтому на выходе получается некруглое изображение.