После того как ваше Activity возьмет на себя управление всеми отступами, вы можете использовать API Compose для проверки того, что контент не перекрывается, а интерактивные элементы не перекрываются с системным пользовательским интерфейсом. Эти API также синхронизируют макет вашего приложения с изменениями отступов.
Обработка вставок с помощью отступов или модификаторов размера.
Например, это самый простой способ применения отступов ко всему содержимому вашего приложения:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enableEdgeToEdge() setContent { Box(Modifier.safeDrawingPadding()) { // the rest of the app } } }
Этот фрагмент кода применяет отступы окна safeDrawing в качестве отступов вокруг всего содержимого приложения. Хотя это гарантирует, что интерактивные элементы не будут перекрывать системный интерфейс, это также означает, что ни одна часть приложения не будет отображаться за системным интерфейсом для достижения эффекта «от края до края». Чтобы в полной мере использовать всё окно, необходимо точно настроить места применения отступов для каждого экрана или компонента отдельно.
Все эти типы отступов автоматически анимируются с помощью IME-анимаций, перенесенных в API 21. Соответственно, все ваши макеты, использующие эти отступы, также автоматически анимируются при изменении значений отступов.
Существует три способа работы с отступами для настройки компонуемых макетов:
Модификаторы отступов
Modifier.windowInsetsPadding(windowInsets: WindowInsets) применяет заданные отступы окна в качестве отступов, действуя так же, как и Modifier.padding . Например, Modifier.windowInsetsPadding(WindowInsets.safeDrawing) применяет безопасные отступы в качестве отступов со всех 4 сторон.
Существует также несколько встроенных вспомогательных методов для наиболее распространенных типов отступов. Modifier.safeDrawingPadding() — один из таких методов, эквивалентный Modifier.windowInsetsPadding(WindowInsets.safeDrawing) . Аналогичные модификаторы существуют и для других типов отступов.
Модификаторы размера вставки
Следующие модификаторы применяют величину отступа окна, задавая размер компонента равным размеру отступа:
Применяет начальную сторону windowInsets в качестве ширины (аналогично | |
Применяет ширину к торцу windowInset (аналогично | |
Применяет верхнюю границу windowInset в качестве высоты (аналогично | |
| Применяет нижнюю границу windowInset в качестве высоты (аналогично |
Эти модификаторы особенно полезны для определения размеров Spacer , которая заполняет пространство, занимаемое вставками:
LazyColumn( Modifier.imePadding() ) { // Other content item { Spacer( Modifier.windowInsetsBottomHeight( WindowInsets.systemBars ) ) } }
Встроенное потребление
Модификаторы отступов ( windowInsetsPadding и вспомогательные функции, такие как safeDrawingPadding ) автоматически занимают ту часть отступов, которая применяется в качестве отступа. При углублении в дерево композиции вложенные модификаторы отступов и модификаторы размера отступа понимают, что часть отступов уже занята внешними модификаторами отступов, и избегают использования одной и той же части отступов более одного раза, что привело бы к излишнему увеличению пространства.
Модификаторы размера вставки также предотвращают повторное использование одной и той же части вставки, если вставки уже были использованы. Однако, поскольку они изменяют свой размер напрямую, сами вставки они не расходуют.
В результате модификаторы отступов при вложенности автоматически изменяют величину отступа, применяемого к каждому составному элементу.
Рассмотрим тот же пример LazyColumn , что и раньше. LazyColumn изменяется в размере с помощью модификатора imePadding . Внутри LazyColumn последний элемент имеет высоту, равную высоте нижней части системных полос:
LazyColumn( Modifier.imePadding() ) { // Other content item { Spacer( Modifier.windowInsetsBottomHeight( WindowInsets.systemBars ) ) } }
Когда IME закрыт, модификатор imePadding() не применяет отступы, поскольку IME не имеет высоты. Поскольку модификатор imePadding() не применяет отступы, отступы не расходуются, и высота Spacer будет равна размеру нижней стороны системных панелей.
Когда открывается окно ввода, отступы окна анимируются, чтобы соответствовать размеру окна, и модификатор imePadding() начинает применять нижний отступ для изменения размера LazyColumn по мере открытия окна. По мере применения нижнего отступа модификатор imePadding() начинает расходовать это количество отступов. Следовательно, высота Spacer начинает уменьшаться, поскольку часть пространства для системных полос уже применена модификатором imePadding() . Как только модификатор imePadding() применяет нижний отступ, превышающий размер системных полос, высота Spacer становится равной нулю.
Когда IME закрывается, изменения происходят в обратном порядке: Spacer начинает расширяться с нулевой высоты, как только imePadding() становится меньше нижней границы системных полос, пока, наконец, высота Spacer не сравняется с высотой нижней границы системных полос после того, как IME полностью анимируется.
TextField . Такое поведение достигается за счет взаимодействия между всеми модификаторами windowInsetsPadding и может быть изменено несколькими другими способами.
Modifier.consumeWindowInsets(insets: WindowInsets) также использует отступы аналогично методу Modifier.windowInsetsPadding , но не применяет использованные отступы в качестве заполнения. Это полезно в сочетании с модификаторами размера отступов, чтобы указать соседним элементам, что определенное количество отступов уже использовано:
Column(Modifier.verticalScroll(rememberScrollState())) { Spacer(Modifier.windowInsetsTopHeight(WindowInsets.systemBars)) Column( Modifier.consumeWindowInsets( WindowInsets.systemBars.only(WindowInsetsSides.Vertical) ) ) { // content Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.ime)) } Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.systemBars)) }
Modifier.consumeWindowInsets(paddingValues: PaddingValues) ведет себя очень похоже на версию с аргументом WindowInsets , но принимает произвольное значение PaddingValues для обработки. Это полезно для информирования дочерних элементов о том, когда отступы или промежутки обеспечиваются каким-либо другим механизмом, помимо модификаторов отступов, например, обычным Modifier.padding или разделителями фиксированной высоты:
Column(Modifier.padding(16.dp).consumeWindowInsets(PaddingValues(16.dp))) { // content Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.ime)) }
В случаях, когда необходимы исходные значения отступов окна без учета их потребления, используйте значения WindowInsets напрямую или используйте WindowInsets.asPaddingValues() для возврата PaddingValues значений отступов, которые не изменяются при потреблении. Однако, ввиду следующих особенностей, по возможности предпочтительнее использовать модификаторы отступов и размера отступов окна.
Вставки и этапы композиции Jetpack
В Compose для обновления и анимации отступов используются базовые API AndroidX, а отступы, в свою очередь, управляются API платформы. Из-за такого поведения платформы отступы имеют особую связь с этапами Jetpack Compose .
Значения отступов обновляются после фазы композиции, но до фазы компоновки. Это означает, что при чтении значений отступов в фазе композиции обычно используется значение отступов на один кадр позже. Встроенные модификаторы, описанные на этой странице, созданы таким образом, чтобы откладывать использование значений отступов до фазы компоновки, что гарантирует использование значений отступов в том же кадре, в котором они обновляются.