Ограничения и порядок модификаторов

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

На этой странице описывается, как связанные модификаторы влияют на ограничения и, в свою очередь, на измерение и размещение составных элементов.

Модификаторы в дереве пользовательского интерфейса

Чтобы понять, как модификаторы влияют друг на друга, полезно визуализировать, как они отображаются в дереве пользовательского интерфейса, которое создается на этапе композиции. Более подробную информацию смотрите в разделе Состав .

В дереве пользовательского интерфейса вы можете визуализировать модификаторы как узлы-оболочки для узлов макета:

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

Добавление более одного модификатора к составному элементу создает цепочку модификаторов. Когда вы объединяете несколько модификаторов, каждый узел модификатора оборачивает остальную часть цепочки и узел макета внутри . Например, когда вы объединяете clip и модификатор size , узел модификатора clip оборачивает узел модификатора size , который затем оборачивает узел макета Image .

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

Как показано на рисунке 2, реализация составных элементов Image и Text состоит из цепочки модификаторов, обертывающих один узел макета. Реализации Row и Column — это просто узлы макета, описывающие, как размещать их дочерние элементы.

Древовидная структура была прежней, но теперь каждый узел представляет собой просто макет с множеством узлов-модификаторов, окружающих его.
Рис. 2. Та же древовидная структура, что и на рис. 1, но компонуемые элементы в дереве пользовательского интерфейса визуализируются как цепочки модификаторов.

Подводя итог:

  • Модификаторы оборачивают один модификатор или узел макета.
  • Узлы макета могут размещать несколько дочерних узлов.

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

Ограничения на этапе макетирования

Фаза макета следует трехэтапному алгоритму для определения ширины, высоты и координаты x, y каждого узла макета:

  1. Измерить дочерние элементы : узел измеряет своих дочерних элементов, если таковые имеются.
  2. Определите собственный размер : на основе этих измерений узел определяет свой собственный размер.
  3. Разместить дочерние элементы : каждый дочерний узел размещается относительно собственной позиции узла.

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

Типы ограничений

Ограничение может быть одним из следующих:

  • Ограниченный : узел имеет максимальную и минимальную ширину и высоту.
Ограниченные ограничения разных размеров внутри контейнера.
Рисунок 3. Ограниченные ограничения.
  • Неограниченный : размер узла не ограничен. Максимальные границы ширины и высоты установлены на бесконечность.
Неограниченные ограничения, у которых ширина и высота равны бесконечности. Ограничения выходят за пределы контейнера.
Рисунок 4. Неограниченные ограничения.
  • Точный : узлу предлагается следовать точным требованиям к размеру. Минимальная и максимальная границы установлены на одно и то же значение.
Точные ограничения, соответствующие точным требованиям к размеру внутри контейнера.
Рисунок 5. Точные ограничения.
  • Комбинация : узел следует за комбинацией вышеуказанных типов ограничений. Например, ограничение может ограничивать ширину, допуская неограниченную максимальную высоту, или устанавливать точную ширину, но обеспечивать ограниченную высоту.
Два контейнера, которые показывают комбинации ограниченных и неограниченных ограничений, а также точную ширину и высоту.
Рисунок 6. Комбинации ограниченных и неограниченных ограничений и точных значений ширины и высоты.

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

Как ограничения передаются от родителя к дочернему элементу

На первом этапе алгоритма, описанного в разделе «Ограничения на этапе макета» , ограничения передаются от родительского элемента к дочернему в дереве пользовательского интерфейса.

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

На высоком уровне алгоритм работает следующим образом:

  1. Чтобы определить размер, который он действительно хочет занимать, корневой узел в дереве пользовательского интерфейса измеряет свои дочерние элементы и пересылает те же ограничения своему первому дочернему элементу.
  2. Если дочерний элемент является модификатором, который не влияет на измерение, он передает ограничения следующему модификатору. Ограничения передаются по цепочке модификаторов как есть, пока не будет достигнут модификатор, влияющий на измерение. Затем ограничения соответствующим образом изменяются.
  3. Как только достигается узел, не имеющий дочерних элементов (называемый «листовым узлом»), он определяет его размер на основе переданных ограничений и возвращает этот разрешенный размер своему родительскому элементу.
  4. Родительский элемент адаптирует свои ограничения на основе измерений этого дочернего элемента и вызывает своего следующего дочернего элемента с этими скорректированными ограничениями.
  5. После того, как все дочерние элементы родительского узла измерены, родительский узел определяет свой собственный размер и сообщает об этом своему родительскому узлу.
  6. Таким образом, все дерево просматривается в глубину. В конце концов, все узлы определились со своими размерами, и этап измерения завершен.

Подробный пример см. в видеоролике « Ограничения и порядок модификаторов» .

Модификаторы, влияющие на ограничения

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

модификатор size

Модификатор size объявляет предпочтительный размер содержимого.

Например, следующее дерево пользовательского интерфейса должно отображаться в контейнере размером 300dp на 200dp . Ограничения ограничены, что позволяет использовать ширину от 100dp до 300dp и высоту от 100dp до 200dp :

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

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

То же, что на рисунке 7, за исключением того, что модификатор размера адаптирует входящие ограничения в соответствии с переданным в него значением.
Рисунок 8. Модификатор size , настраивающий ограничения на 150dp .

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

Два дерева пользовательского интерфейса и соответствующие им представления в контейнерах. В первом случае   модификатор размера принимает входящие ограничения; во втором модификатор размера адаптируется к   слишком большие ограничения как можно ближе, в результате чего ограничения заполняют контейнер.
Рисунок 9. Модификатор size , максимально точно соответствующий переданному ограничению.

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

Цепочка из двух модификаторов размера в дереве пользовательского интерфейса и его представление в контейнере,   который является результатом переданного первого значения, а не второго значения.
Рисунок 10. Цепочка из двух модификаторов size , в которой переданное второе значение ( 50dp ) не переопределяет первое значение ( 100dp ).

модификатор requiredSize

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

Когда размер передается обратно вверх по дереву, дочерний узел будет центрирован в доступном пространстве:

Модификатор size и requireSize, связанные в дереве пользовательского интерфейса, и соответствующий   представление в контейнере. Ограничения модификатора требуемого размера переопределяют модификатор размера.   ограничения.
Рисунок 11. Модификатор requiredSize , переопределяющий входящие ограничения модификатора size .

модификаторы width и height

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

Два дерева пользовательского интерфейса: одно с модификатором ширины и его контейнерным представлением, а другое.   с модификатором высоты и его представлением.
Рисунок 12. Модификатор width и модификатор height , задающие фиксированную ширину и высоту соответственно.

модификатор sizeIn

Модификатор sizeIn позволяет вам установить точные минимальные и максимальные ограничения для ширины и высоты. Используйте модификатор sizeIn если вам нужен детальный контроль над ограничениями.

Дерево пользовательского интерфейса с модификатором sizeIn с установленными минимальной и максимальной шириной и высотой,   и его представление внутри контейнера.
Рисунок 13. Модификатор sizeIn с установленными minWidth , maxWidth , minHeight и maxHeight .

Примеры

В этом разделе показаны и объяснены выходные данные нескольких фрагментов кода со связанными модификаторами.

Image(
    painterResource(R.drawable.hero),
    contentDescription = null,
    Modifier
        .fillMaxSize()
        .size(50.dp)
)

Этот фрагмент выдает следующий результат:

  • Модификатор 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)
)

Этот фрагмент выдает следующий результат:

  • Модификатор 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 соответствует этим ограничениям и имеет размер 100 на 100dp .
    • Модификатор padding добавляет 10dp ко всем размерам, поэтому увеличивает сообщаемую ширину и высоту на 20dp .
    • Теперь на этапе рисования модификатор clip действует на холсте размером 120 на 120dp . Итак, он создает круглую маску такого размера .
    • Модификатор padding затем вставляет содержимое на 10dp для всех размеров, поэтому он уменьшает размер холста до 100 на 100dp .
    • Image нарисовано на этом холсте. Изображение обрезается на основе исходного круга с 120dp , поэтому на выходе получается некруглый результат.
,

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

На этой странице описывается, как связанные модификаторы влияют на ограничения и, в свою очередь, на измерение и размещение составных элементов.

Модификаторы в дереве пользовательского интерфейса

Чтобы понять, как модификаторы влияют друг на друга, полезно визуализировать, как они отображаются в дереве пользовательского интерфейса, которое создается на этапе композиции. Более подробную информацию смотрите в разделе Состав .

В дереве пользовательского интерфейса вы можете визуализировать модификаторы как узлы-оболочки для узлов макета:

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

Добавление более одного модификатора к составному элементу создает цепочку модификаторов. Когда вы объединяете несколько модификаторов, каждый узел модификатора оборачивает остальную часть цепочки и узел макета внутри . Например, когда вы объединяете clip и модификатор size , узел модификатора clip оборачивает узел модификатора size , который затем оборачивает узел макета Image .

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

Как показано на рисунке 2, реализация составных элементов Image и Text состоит из цепочки модификаторов, обертывающих один узел макета. Реализации Row и Column — это просто узлы макета, которые описывают, как размещать их дочерние элементы.

Древовидная структура была прежней, но теперь каждый узел представляет собой просто макет с множеством узлов-модификаторов, окружающих его.
Рис. 2. Та же древовидная структура, что и на рис. 1, но компонуемые элементы в дереве пользовательского интерфейса визуализируются как цепочки модификаторов.

Подводя итог:

  • Модификаторы оборачивают один модификатор или узел макета.
  • Узлы макета могут размещать несколько дочерних узлов.

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

Ограничения на этапе макетирования

Фаза макета следует трехэтапному алгоритму для определения ширины, высоты и координаты x, y каждого узла макета:

  1. Измерить дочерние элементы : узел измеряет своих дочерних элементов, если таковые имеются.
  2. Определите собственный размер : на основе этих измерений узел определяет свой собственный размер.
  3. Разместить дочерние элементы : каждый дочерний узел размещается относительно собственной позиции узла.

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

Типы ограничений

Ограничение может быть одним из следующих:

  • Ограниченный : узел имеет максимальную и минимальную ширину и высоту.
Ограниченные ограничения разных размеров внутри контейнера.
Рисунок 3. Ограниченные ограничения.
  • Неограниченный : размер узла не ограничен. Максимальные границы ширины и высоты установлены на бесконечность.
Неограниченные ограничения, у которых ширина и высота равны бесконечности. Ограничения выходят за пределы контейнера.
Рисунок 4. Неограниченные ограничения.
  • Точный : узлу предлагается следовать точным требованиям к размеру. Минимальная и максимальная границы установлены на одно и то же значение.
Точные ограничения, соответствующие точным требованиям к размеру внутри контейнера.
Рисунок 5. Точные ограничения.
  • Комбинация : узел следует за комбинацией вышеуказанных типов ограничений. Например, ограничение может ограничивать ширину, допуская неограниченную максимальную высоту, или устанавливать точную ширину, но обеспечивать ограниченную высоту.
Два контейнера, которые показывают комбинации ограниченных и неограниченных ограничений, а также точную ширину и высоту.
Рисунок 6. Комбинации ограниченных и неограниченных ограничений и точных значений ширины и высоты.

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

Как ограничения передаются от родителя к дочернему элементу

На первом этапе алгоритма, описанного в разделе «Ограничения на этапе макета» , ограничения передаются от родительского элемента к дочернему в дереве пользовательского интерфейса.

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

На высоком уровне алгоритм работает следующим образом:

  1. Чтобы определить размер, который он действительно хочет занимать, корневой узел в дереве пользовательского интерфейса измеряет свои дочерние элементы и пересылает те же ограничения своему первому дочернему элементу.
  2. Если дочерний элемент является модификатором, который не влияет на измерение, он передает ограничения следующему модификатору. Ограничения передаются по цепочке модификаторов как есть, пока не будет достигнут модификатор, влияющий на измерение. Затем ограничения соответствующим образом изменяются.
  3. Как только достигается узел, не имеющий дочерних элементов (называемый «листовым узлом»), он определяет его размер на основе переданных ограничений и возвращает этот разрешенный размер своему родительскому элементу.
  4. Родительский элемент адаптирует свои ограничения на основе измерений этого дочернего элемента и вызывает своего следующего дочернего элемента с этими скорректированными ограничениями.
  5. После того, как все дочерние элементы родительского узла измерены, родительский узел определяет свой собственный размер и сообщает об этом своему родительскому узлу.
  6. Таким образом, все дерево просматривается в глубину. В конце концов, все узлы определились со своими размерами, и этап измерения завершен.

Подробный пример см. в видеоролике « Ограничения и порядок модификаторов» .

Модификаторы, влияющие на ограничения

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

модификатор size

Модификатор size объявляет предпочтительный размер содержимого.

Например, следующее дерево пользовательского интерфейса должно отображаться в контейнере размером 300dp на 200dp . Ограничения ограничены, что позволяет использовать ширину от 100dp до 300dp и высоту от 100dp до 200dp :

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

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

То же, что на рисунке 7, за исключением того, что модификатор размера адаптирует входящие ограничения в соответствии с переданным в него значением.
Рисунок 8. Модификатор size , настраивающий ограничения на 150dp .

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

Два дерева пользовательского интерфейса и соответствующие им представления в контейнерах. В первом случае   модификатор размера принимает входящие ограничения; во втором модификатор размера адаптируется к   слишком большие ограничения как можно ближе, в результате чего ограничения заполняют контейнер.
Рисунок 9. Модификатор size , максимально точно соответствующий переданному ограничению.

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

Цепочка из двух модификаторов размера в дереве пользовательского интерфейса и его представление в контейнере,   который является результатом переданного первого значения, а не второго значения.
Рисунок 10. Цепочка из двух модификаторов size , в которой переданное второе значение ( 50dp ) не переопределяет первое значение ( 100dp ).

модификатор requiredSize

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

Когда размер передается обратно вверх по дереву, дочерний узел будет центрирован в доступном пространстве:

Модификатор size и requireSize, связанные в дереве пользовательского интерфейса, и соответствующий   представление в контейнере. Ограничения модификатора требуемого размера переопределяют модификатор размера.   ограничения.
Рисунок 11. Модификатор requiredSize , переопределяющий входящие ограничения модификатора size .

модификаторы width и height

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

Два дерева пользовательского интерфейса: одно с модификатором ширины и его контейнерным представлением, а другое.   с модификатором высоты и его представлением.
Рисунок 12. Модификатор width и модификатор height , задающие фиксированную ширину и высоту соответственно.

модификатор sizeIn

Модификатор sizeIn позволяет вам установить точные минимальные и максимальные ограничения для ширины и высоты. Используйте модификатор sizeIn если вам нужен детальный контроль над ограничениями.

Дерево пользовательского интерфейса с модификатором sizeIn с установленными минимальной и максимальной шириной и высотой,   и его представление внутри контейнера.
Рисунок 13. Модификатор sizeIn с установленными minWidth , maxWidth , minHeight и maxHeight .

Примеры

В этом разделе показаны и объяснены выходные данные нескольких фрагментов кода со связанными модификаторами.

Image(
    painterResource(R.drawable.hero),
    contentDescription = null,
    Modifier
        .fillMaxSize()
        .size(50.dp)
)

Этот фрагмент выдает следующий результат:

  • Модификатор 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)
)

Этот фрагмент выдает следующий результат:

  • Модификатор 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 соответствует этим ограничениям и имеет размер 100 на 100dp .
    • Модификатор padding добавляет 10dp ко всем размерам, поэтому увеличивает сообщаемую ширину и высоту на 20dp .
    • Теперь на этапе рисования модификатор clip действует на холсте размером 120 на 120dp . Итак, он создает круглую маску такого размера .
    • Модификатор padding затем вставляет содержимое на 10dp для всех размеров, поэтому он уменьшает размер холста до 100 на 100dp .
    • Image нарисовано на этом холсте. Изображение обрезается на основе исходного круга с 120dp , поэтому на выходе получается некруглый результат.
,

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

На этой странице описывается, как связанные модификаторы влияют на ограничения и, в свою очередь, на измерение и размещение составных элементов.

Модификаторы в дереве пользовательского интерфейса

Чтобы понять, как модификаторы влияют друг на друга, полезно визуализировать, как они отображаются в дереве пользовательского интерфейса, которое создается на этапе композиции. Более подробную информацию смотрите в разделе Состав .

В дереве пользовательского интерфейса вы можете визуализировать модификаторы как узлы-оболочки для узлов макета:

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

Добавление более одного модификатора к составному элементу создает цепочку модификаторов. Когда вы объединяете несколько модификаторов, каждый узел модификатора оборачивает остальную часть цепочки и узел макета внутри . Например, когда вы объединяете clip и модификатор size , узел модификатора clip оборачивает узел модификатора size , который затем оборачивает узел макета Image .

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

Как показано на рисунке 2, реализация составных элементов Image и Text состоит из цепочки модификаторов, обертывающих один узел макета. Реализации Row и Column — это просто узлы макета, описывающие, как размещать их дочерние элементы.

Древовидная структура была прежней, но теперь каждый узел представляет собой просто макет с множеством узлов-модификаторов, окружающих его.
Рис. 2. Та же древовидная структура, что и на рис. 1, но компонуемые элементы в дереве пользовательского интерфейса визуализируются как цепочки модификаторов.

Подводя итог:

  • Модификаторы оборачивают один модификатор или узел макета.
  • Узлы макета могут размещать несколько дочерних узлов.

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

Ограничения на этапе макетирования

Фаза макета следует трехэтапному алгоритму для определения ширины, высоты и координаты x, y каждого узла макета:

  1. Измерить дочерние элементы : узел измеряет своих дочерних элементов, если таковые имеются.
  2. Определите собственный размер : на основе этих измерений узел определяет свой собственный размер.
  3. Разместить дочерние элементы : каждый дочерний узел размещается относительно собственной позиции узла.

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

Типы ограничений

Ограничение может быть одним из следующих:

  • Ограниченный : узел имеет максимальную и минимальную ширину и высоту.
Ограниченные ограничения разных размеров внутри контейнера.
Рисунок 3. Ограниченные ограничения.
  • Неограниченный : размер узла не ограничен. Максимальные границы ширины и высоты установлены на бесконечность.
Неограниченные ограничения, у которых ширина и высота равны бесконечности. Ограничения выходят за пределы контейнера.
Рисунок 4. Неограниченные ограничения.
  • Точный : узлу предлагается следовать точным требованиям к размеру. Минимальная и максимальная границы установлены на одно и то же значение.
Точные ограничения, соответствующие точным требованиям к размеру внутри контейнера.
Рисунок 5. Точные ограничения.
  • Комбинация : узел следует за комбинацией вышеуказанных типов ограничений. Например, ограничение может ограничивать ширину, допуская неограниченную максимальную высоту, или устанавливать точную ширину, но обеспечивать ограниченную высоту.
Два контейнера, которые показывают комбинации ограниченных и неограниченных ограничений, а также точную ширину и высоту.
Рисунок 6. Комбинации ограниченных и неограниченных ограничений и точных значений ширины и высоты.

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

Как ограничения передаются от родителя к дочернему элементу

На первом этапе алгоритма, описанного в разделе «Ограничения на этапе макета» , ограничения передаются от родительского элемента к дочернему в дереве пользовательского интерфейса.

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

На высоком уровне алгоритм работает следующим образом:

  1. Чтобы определить размер, который он действительно хочет занимать, корневой узел в дереве пользовательского интерфейса измеряет свои дочерние элементы и пересылает те же ограничения своему первому дочернему элементу.
  2. Если дочерний элемент является модификатором, который не влияет на измерение, он передает ограничения следующему модификатору. Ограничения передаются по цепочке модификаторов как есть, пока не будет достигнут модификатор, влияющий на измерение. Затем ограничения соответствующим образом изменяются.
  3. Как только достигается узел, не имеющий дочерних элементов (называемый «листовым узлом»), он определяет его размер на основе переданных ограничений и возвращает этот разрешенный размер своему родительскому элементу.
  4. Родительский элемент адаптирует свои ограничения на основе измерений этого дочернего элемента и вызывает своего следующего дочернего элемента с этими скорректированными ограничениями.
  5. После того, как все дочерние элементы родительского узла измерены, родительский узел определяет свой собственный размер и сообщает об этом своему родительскому узлу.
  6. Таким образом, все дерево просматривается в глубину. В конце концов, все узлы определились со своими размерами, и этап измерения завершен.

Подробный пример см. в видеоролике « Ограничения и порядок модификаторов» .

Модификаторы, влияющие на ограничения

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

модификатор size

Модификатор size объявляет предпочтительный размер содержимого.

Например, следующее дерево пользовательского интерфейса должно отображаться в контейнере размером 300dp на 200dp . Ограничения ограничены, что позволяет использовать ширину от 100dp до 300dp и высоту от 100dp до 200dp :

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

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

То же, что на рисунке 7, за исключением того, что модификатор размера адаптирует входящие ограничения в соответствии с переданным в него значением.
Рисунок 8. Модификатор size , настраивающий ограничения на 150dp .

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

Два дерева пользовательского интерфейса и соответствующие им представления в контейнерах. В первом случае   модификатор размера принимает входящие ограничения; во втором модификатор размера адаптируется к   слишком большие ограничения как можно ближе, в результате чего ограничения заполняют контейнер.
Рисунок 9. Модификатор size , максимально точно соответствующий переданному ограничению.

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

Цепочка из двух модификаторов размера в дереве пользовательского интерфейса и его представление в контейнере,   который является результатом переданного первого значения, а не второго значения.
Рисунок 10. Цепочка из двух модификаторов size , в которой переданное второе значение ( 50dp ) не переопределяет первое значение ( 100dp ).

модификатор requiredSize

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

Когда размер передается обратно по дереву, детский узел будет центрироваться в доступном пространстве:

Размер и модификатор обязательного размера, прикованные в дереве пользовательского интерфейса, и соответствующий   Представление в контейнере. Ограничения модификатора требуемого размера переопределяют модификатор размера   ограничения.
Рисунок 11. Модификатор requiredSize переоценивает входящие ограничения из модификатора size .

Модификаторы width и height

Модификатор size адаптирует как ширину, так и высоту ограничений. С модификатором width вы можете установить фиксированную ширину, но оставить высоту нерешенной. Точно так же, с модификатором height , вы можете установить фиксированную высоту, но оставить ширину нерешенной:

Два дерева пользовательского интерфейса, одно с модификатором ширины, его контейнерным представлением, а другой   с модификатором высоты и его представлением.
Рисунок 12. Модификатор width и модификатор height , устанавливающие фиксированную ширину и высоту соответственно.

модификатор sizeIn

Модификатор sizeIn позволяет устанавливать точные минимальные и максимальные ограничения для ширины и высоты. Используйте модификатор sizeIn если вам нужен мелкозернистый контроль над ограничениями.

Дерево пользовательского интерфейса с модификатором размера с минимальной и максимальной шириной и установленными высоты,   и его представление в контейнере.
Рисунок 13. Модификатор sizeIn с minWidth , maxWidth , minHeight и maxHeight Set.

Примеры

В этом разделе показан и объясняет выход из нескольких фрагментов кода с цепными модификаторами.

Image(
    painterResource(R.drawable.hero),
    contentDescription = null,
    Modifier
        .fillMaxSize()
        .size(50.dp)
)

Этот фрагмент создает следующий выход:

  • Модификатор 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)
)

Этот фрагмент создает следующий выход:

  • Модификатор 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 придерживается этих ограничений и сообщает размер 100 на 100dp .
    • Модификатор padding добавляет 10dp на всех размерах, поэтому он увеличивает сообщаемую ширину и высоту на 20dp .
    • Теперь на этапе рисования модификатор clip действует на холсте 120 на 120dp . Итак, это создает круговую маску такого размера .
    • Затем модификатор padding вставляет его содержание на 10dp на всех размерах, поэтому он снижает размер холста до 100 на 100dp .
    • Image нарисовано в этом холсте. Изображение обрезано на основе исходного круга 120dp , поэтому выход не является раундовым результатом.
,

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

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

Модификаторы в дереве пользовательского интерфейса

Чтобы понять, как модификаторы влияют друг на друга, полезно визуализировать, как они появляются в дереве пользовательского интерфейса, которое генерируется на этапе композиции. Для получения дополнительной информации см. Раздел композиции .

В дереве пользовательского интерфейса вы можете визуализировать модификаторы в виде узлов обертки для узлов макета:

Код для композиционных и модификаторов, а также их визуальное представление в качестве дерева пользовательского интерфейса.
Рисунок 1. Модификаторы обмотавших узлов макета в дереве пользовательского интерфейса.

Добавление более одного модификатора в композицию создает цепь модификаторов. Когда вы цепляетесь с несколькими модификаторами, каждый узел модификатора завершает остальную часть цепи и узлом макета внутри . Например, когда вы подготовите clip и модификатор size , узел Modifier clip завершает узел модификатора size , который затем завершает узел макета Image .

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

Как показано на рисунке 2, реализация самих композиционных компаний Image и Text состоят из цепочки модификаторов, обертывающих один узел макета. Реализации Row и Column - это просто узлы макета, которые описывают, как выложить своих детей.

Структура дерева из ранее, но теперь каждый узел - это просто простой макет, с большим количеством модификатора обертывания узлов вокруг него.
Рисунок 2. Та же самая структура дерева, что и на рисунке 1, но с композиционными устройствами в дереве пользовательского интерфейса, визуализированной как цепочки модификаторов.

Подводя итог:

  • Модификаторы обертывают один модификатор или узел макета.
  • Узлы макета могут изложить несколько дочерних узлов.

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

Ограничения на этапе макета

Фаза макета следует за трехэтапным алгоритмом, чтобы найти ширину, высоту и координату каждого узла каждого макета:

  1. Измеряйте детей : узел измеряет своих детей, если таковые имеются.
  2. Решите собственный размер : на основе этих измерений, узел решает свой собственный размер.
  3. Размещайте детей : каждый узел ребенка размещен по сравнению с собственной позицией узла.

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

Типы ограничений

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

  • Ограниченный : узел имеет максимальную и минимальную ширину и высоту.
Ограниченные ограничения разных размеров в контейнере.
Рисунок 3. Ограниченные ограничения.
  • Несоограничен : узел не ограничен ни одного размера. Максимальная ширина и границы высоты устанавливаются на бесконечность.
Неограниченные ограничения, которые имеют ширину и высоту, установленные для бесконечности. Ограничения простираются за пределы контейнера.
Рисунок 4. Неуграниченные ограничения.
  • Точно : узел просят следовать требованию точного размера. Минимальные и максимальные границы устанавливаются на то же значение.
Точные ограничения, которые соответствуют требованиям точного размера в контейнере.
Рисунок 5. Точные ограничения.
  • Комбинация : Узел следует за комбинацией вышеуказанных типов ограничений. Например, ограничение может связать ширину, обеспечивая неограниченную максимальную высоту, или установить точную ширину, но обеспечить ограниченную высоту.
Два контейнера, которые показывают комбинации ограниченных и неограниченных ограничений, точных ширины и высот.
Рисунок 6. Комбинации ограниченных и неограниченных ограничений и точных ширины и высот.

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

Как ограничения передаются от родителя к ребенку

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

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

На высоком уровне алгоритм работает следующим образом:

  1. Чтобы решить размер, который он на самом деле хочет занять, корневой узел в дереве пользовательского интерфейса измеряет своих детей и направляет такие же ограничения на своего первого ребенка.
  2. Если ребенок является модификатором, который не влияет на измерение, он направляет ограничения на следующий модификатор. Ограничения передаются вниз по цепочке модификаторов AS IS, если не достигнут модификатор, который влияет на измерение. Ограничения затем переоценивают соответственно.
  3. Как только узел достигнут, у которого нет детей (называемый «листовым узлом»), он решает его размер на основе ограничений, которые были переданы, и возвращает этот разрешенный размер своему родителю.
  4. Родитель адаптирует свои ограничения на основе измерений этого ребенка и называет его следующего ребенка с этими скорректированными ограничениями.
  5. Как только все дети родителей измеряются, родительский узел решает свой собственный размер и сообщает об этом своему родителю.
  6. Таким образом, все дерево пересекается в первую очередь. В конце концов, все узлы определились с их размерами, и этап измерения завершен.

Для углубленного примера см. В видео ограничения и модификатора .

Модификаторы, которые влияют на ограничения

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

модификатор size

Модификатор size объявляет предпочтительный размер контента.

Например, следующее дерево пользовательского интерфейса должно быть отображено в контейнере с 300dp На 200dp . Ограничения ограничены, позволяя ширина от 100dp до 300dp , и высоты между 100dp 200dp

Часть дерева пользовательского интерфейса с модификатором размера обертывает узел макета, и   Представление ограниченных ограничений, установленных модификатором размера в контейнере.
Рисунок 7. Ограниченные ограничения в дереве пользовательского интерфейса и его представление в контейнере.

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

То же самое, что и рисунок 7, за исключением того, что модификатор размера адаптирует входящие ограничения, чтобы соответствовать передаваемому ему значение.
Рисунок 8. Регулирующий ограничение модификатора size до 150dp .

Если ширина и высота меньше, чем наименьшее ограничение, или больше, чем самое большое ограничение, модификатор соответствует передаваемым ограничениям так близко, насколько это возможно, при этом придерживаясь ограничений, передаваемых:

Два дерева пользовательского интерфейса и соответствующие представления в контейнерах. Во -первых,   Модификатор размера принимает ограничения инчаминга; Во втором модификатор размера адаптируется к   Слишком большие ограничения максимально близко, что приводит к ограничениям, которые заполняют контейнер.
Рисунок 9. Модификатор size , придерживающийся как можно ближе к пропущенному ограничению.

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

Цепочка из двух модификаторов размера в дереве пользовательского интерфейса и ее представления в контейнере,   что является результатом первого значения, пройденного, а не второе значение.
Рисунок 10. Цепочка из двух модификаторов size , в которой второе значение проходило в ( 50dp ), не переопределяет первое значение ( 100dp ).

модификатор requiredSize

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

Когда размер передается обратно по дереву, детский узел будет центрироваться в доступном пространстве:

Размер и модификатор обязательного размера, прикованные в дереве пользовательского интерфейса, и соответствующий   Представление в контейнере. Ограничения модификатора требуемого размера переопределяют модификатор размера   ограничения.
Рисунок 11. Модификатор requiredSize переоценивает входящие ограничения из модификатора size .

Модификаторы width и height

Модификатор size адаптирует как ширину, так и высоту ограничений. С модификатором width вы можете установить фиксированную ширину, но оставить высоту нерешенной. Точно так же, с модификатором height , вы можете установить фиксированную высоту, но оставить ширину нерешенной:

Два дерева пользовательского интерфейса, одно с модификатором ширины, его контейнерным представлением, а другой   с модификатором высоты и его представлением.
Рисунок 12. Модификатор width и модификатор height , устанавливающие фиксированную ширину и высоту соответственно.

модификатор sizeIn

Модификатор sizeIn позволяет устанавливать точные минимальные и максимальные ограничения для ширины и высоты. Используйте модификатор sizeIn если вам нужен мелкозернистый контроль над ограничениями.

Дерево пользовательского интерфейса с модификатором размера с минимальной и максимальной шириной и установленными высоты,   и его представление в контейнере.
Рисунок 13. Модификатор sizeIn с minWidth , maxWidth , minHeight и maxHeight Set.

Примеры

В этом разделе показан и объясняет выход из нескольких фрагментов кода с цепными модификаторами.

Image(
    painterResource(R.drawable.hero),
    contentDescription = null,
    Modifier
        .fillMaxSize()
        .size(50.dp)
)

Этот фрагмент создает следующий выход:

  • Модификатор 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)
)

Этот фрагмент создает следующий выход:

  • Модификатор 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 придерживается этих ограничений и сообщает размер 100 на 100dp .
    • Модификатор padding добавляет 10dp на всех размерах, поэтому он увеличивает сообщаемую ширину и высоту на 20dp .
    • Теперь на этапе рисования модификатор clip действует на холсте 120 на 120dp . Итак, это создает круговую маску такого размера .
    • Затем модификатор padding вставляет его содержание на 10dp на всех размерах, поэтому он снижает размер холста до 100 на 100dp .
    • Image нарисовано в этом холсте. Изображение обрезано на основе исходного круга 120dp , поэтому выход не является раундовым результатом.