Всплывающие окна
Всплывающее окно в Compose Multiplatform — это плавающий контейнер, который отображает свое содержимое поверх текущего пользовательского интерфейса в том же окне.
В отличие от API Dialog() для мультиплатформенной разработки, Popup() не является модальным. Диалоговое окно в Compose Multiplatform — это модальный контейнер, который получает фокус, размещает содержимое по центру и использует затемненный фон, блокирующий взаимодействие с остальной частью пользовательского интерфейса. Всплывающее окно, напротив, не имеет затемненного фона, не ограничивает ширину и позволяет пользователям продолжать взаимодействовать с лежащим под ним интерфейсом. По умолчанию оно не центрируется, и для привязки к компоненту нужны дополнительные аргументы.
Используйте Dialog(), если нужно прервать пользователя и получить от него решение, прежде чем он продолжит, например, запросить подтверждение, показать предупреждение или предложить заполнить короткую форму. Сведения об отдельных диалоговых окнах на уровне ОС в настольных приложениях см. в разделе DialogWindow(). Используйте Popup() для легковесных, неблокирующих наложений, привязанных к компоненту в текущем окне, таких как раскрывающиеся списки, всплывающие подсказки и меню.
Размещение всплывающего окна
Чтобы задать положение всплывающего окна, используйте alignment и offset либо собственный PopupPositionProvider для привязки к компоненту.
Для простого выравнивания:
var isPopupOpen by remember { mutableStateOf(false) }
Box(Modifier.padding(24.dp)) {
Button(onClick = { isPopupOpen = !isPopupOpen }) {
Text("Toggle popup")
}
if (isPopupOpen) {
Popup(
// Positions the popup relative to the button
alignment = Alignment.TopStart,
// Shifts the popup by (x, y) in pixels
offset = IntOffset(30, 70),
// Hides the popup when it is dismissed,
// for example, when the user clicks outside it
onDismissRequest = { isPopupOpen = false }
) {
Box(
Modifier
.background(Color.LightGray, RoundedCornerShape(4.dp))
.padding(12.dp)
) {
Text("Popup content on top of UI")
}
}
}
}
Для привязки к компоненту используйте PopupPositionProvider:
var isPopupOpen by remember { mutableStateOf(false) }
val belowAnchor = remember {
object : PopupPositionProvider {
override fun calculatePosition(
anchorBounds: IntRect,
windowSize: IntSize,
layoutDirection: LayoutDirection,
popupContentSize: IntSize
) = IntOffset(x = anchorBounds.left - 20, y = anchorBounds.bottom - 20)
}
}
Column(Modifier.padding(24.dp)) {
Box {
Button(onClick = { isPopupOpen = !isPopupOpen }) {
Text("Toggle menu")
}
if (isPopupOpen) {
Popup(
popupPositionProvider = belowAnchor,
onDismissRequest = { isPopupOpen = false }
) {
Box(
Modifier
.shadow(4.dp, RoundedCornerShape(4.dp))
.background(Color.White, RoundedCornerShape(4.dp))
.padding(12.dp)
) {
Text("Anchored to the button")
}
}
}
}
}
Настройка поведения
С помощью PopupProperties можно управлять получением фокуса и закрытием всплывающего окна:
focusableопределяет, получает ли всплывающее окно события клавиатуры; по умолчанию эта возможность отключена.dismissOnBackPressзакрывает всплывающее окно при нажатии кнопки «Назад» на Android или клавиши Esc на настольном компьютере; по умолчанию эта возможность включена. Требуетсяfocusable = true.dismissOnClickOutsideзакрывает всплывающее окно, когда пользователь нажимает за его пределами; по умолчанию эта возможность включена.
Popup() и его PopupProperties входят в общий API. Однако некоторые свойства недоступны в общем наборе исходного кода. Например, usePlatformInsets доступно на iOS, где оно ограничивает содержимое всплывающего окна системными отступами (безопасной областью).
Что дальше
Полное описание API см. в справочной документации Jetpack Compose:
© 2010–2026 JetBrains s.r.o. and Kotlin Programming Language contributors
Licensed under the Apache License, Version 2.0.
https://kotlinlang.org/docs/multiplatform/compose-popups.html