pref: Dialog 弹出动画
This commit is contained in:
parent
7a3c2c354d
commit
9356f043ed
|
|
@ -35,30 +35,12 @@ import com.ramcosta.composedestinations.annotation.Destination
|
|||
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
|
||||
import com.ramcosta.composedestinations.spec.DestinationStyle
|
||||
|
||||
@Destination
|
||||
@Composable
|
||||
fun CopyTextPage(
|
||||
text: String,
|
||||
navigator: DestinationsNavigator,
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
CopyTextPageContent(
|
||||
text = text,
|
||||
onCopy = {
|
||||
TiebaUtil.copyText(context, it)
|
||||
},
|
||||
onCancel = {
|
||||
navigator.navigateUp()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
object CopyTextDialogStyle : DestinationStyle.Dialog {
|
||||
override val properties: DialogProperties
|
||||
get() = DialogProperties(
|
||||
usePlatformDefaultWidth = false,
|
||||
decorFitsSystemWindows = false
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
@Destination(
|
||||
|
|
@ -70,6 +52,7 @@ fun CopyTextDialogPage(
|
|||
navigator: DestinationsNavigator,
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
|
||||
Box(
|
||||
contentAlignment = Alignment.Center,
|
||||
modifier = Modifier
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ import com.huanchengfly.tieba.post.ui.common.theme.compose.invertChipContent
|
|||
import com.huanchengfly.tieba.post.ui.common.theme.compose.pullRefreshIndicator
|
||||
import com.huanchengfly.tieba.post.ui.common.theme.compose.threadBottomBar
|
||||
import com.huanchengfly.tieba.post.ui.page.ProvideNavigator
|
||||
import com.huanchengfly.tieba.post.ui.page.destinations.CopyTextPageDestination
|
||||
import com.huanchengfly.tieba.post.ui.page.destinations.CopyTextDialogPageDestination
|
||||
import com.huanchengfly.tieba.post.ui.page.destinations.ForumPageDestination
|
||||
import com.huanchengfly.tieba.post.ui.page.destinations.ReplyPageDestination
|
||||
import com.huanchengfly.tieba.post.ui.page.destinations.SubPostsSheetPageDestination
|
||||
|
|
@ -875,7 +875,7 @@ fun ThreadPage(
|
|||
},
|
||||
onMenuCopyClick = {
|
||||
navigator.navigate(
|
||||
CopyTextPageDestination(it)
|
||||
CopyTextDialogPageDestination(it)
|
||||
)
|
||||
},
|
||||
onMenuFavoriteClick = {
|
||||
|
|
@ -1216,7 +1216,7 @@ fun ThreadPage(
|
|||
},
|
||||
onMenuCopyClick = {
|
||||
navigator.navigate(
|
||||
CopyTextPageDestination(it)
|
||||
CopyTextDialogPageDestination(it)
|
||||
)
|
||||
},
|
||||
onMenuFavoriteClick = {
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ import androidx.compose.material.ButtonColors
|
|||
import androidx.compose.material.ButtonDefaults
|
||||
import androidx.compose.material.ButtonElevation
|
||||
import androidx.compose.material.ContentAlpha
|
||||
import androidx.compose.material.ExperimentalMaterialApi
|
||||
import androidx.compose.material.LocalContentAlpha
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.ProvideTextStyle
|
||||
|
|
@ -25,12 +24,12 @@ import androidx.compose.runtime.getValue
|
|||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.Shape
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.huanchengfly.tieba.post.ui.common.theme.compose.ExtendedTheme
|
||||
|
||||
@OptIn(ExperimentalMaterialApi::class)
|
||||
@Composable
|
||||
fun Button(
|
||||
onClick: () -> Unit,
|
||||
|
|
@ -50,6 +49,7 @@ fun Button(
|
|||
val contentColor by colors.contentColor(enabled)
|
||||
Surface(
|
||||
modifier = Modifier
|
||||
.clip(shape)
|
||||
.clickable(
|
||||
onClick = onClick,
|
||||
enabled = enabled,
|
||||
|
|
|
|||
|
|
@ -1,18 +1,33 @@
|
|||
package com.huanchengfly.tieba.post.ui.widgets.compose
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.text.KeyboardActions
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.material.*
|
||||
import androidx.compose.material.ButtonDefaults
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.OutlinedTextField
|
||||
import androidx.compose.material.ProvideTextStyle
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material.TextButton
|
||||
import androidx.compose.material.TextFieldDefaults
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.saveable.Saver
|
||||
import androidx.compose.runtime.saveable.listSaver
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.ExperimentalComposeUiApi
|
||||
import androidx.compose.ui.Modifier
|
||||
|
|
@ -24,9 +39,10 @@ import androidx.compose.ui.text.font.FontWeight
|
|||
import androidx.compose.ui.text.input.ImeAction
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.compose.ui.window.DialogProperties
|
||||
import com.huanchengfly.tieba.post.R
|
||||
import com.huanchengfly.tieba.post.ui.common.theme.compose.ExtendedTheme
|
||||
import com.huanchengfly.tieba.post.ui.widgets.compose.dialogs.AnyPopDialog
|
||||
import com.huanchengfly.tieba.post.ui.widgets.compose.dialogs.AnyPopDialogProperties
|
||||
import com.huanchengfly.tieba.post.ui.widgets.compose.picker.TimePicker
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
|
|
@ -305,71 +321,60 @@ fun Dialog(
|
|||
content: @Composable (DialogScope.() -> Unit),
|
||||
) {
|
||||
if (dialogState.show) {
|
||||
var isActiveClose by remember {
|
||||
mutableStateOf(false)
|
||||
}
|
||||
val dialogScope = DialogScope(
|
||||
onDismiss = onDismiss,
|
||||
dialogState = dialogState,
|
||||
onDismiss = {
|
||||
isActiveClose = true
|
||||
},
|
||||
)
|
||||
androidx.compose.ui.window.Dialog(
|
||||
onDismissRequest = { dialogScope.dismiss() },
|
||||
properties = DialogProperties(
|
||||
usePlatformDefaultWidth = false,
|
||||
AnyPopDialog(
|
||||
isActiveClose = isActiveClose,
|
||||
onDismiss = {
|
||||
onDismiss?.invoke()
|
||||
dialogState.show = false
|
||||
},
|
||||
properties = AnyPopDialogProperties(
|
||||
dismissOnBackPress = cancelable,
|
||||
dismissOnClickOutside = cancelableOnTouchOutside
|
||||
)
|
||||
) {
|
||||
Box(modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.clickable(
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
indication = null,
|
||||
enabled = cancelableOnTouchOutside
|
||||
) {
|
||||
dialogScope.dismiss()
|
||||
}
|
||||
Column(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.padding(16.dp)
|
||||
.background(
|
||||
color = ExtendedTheme.colors.windowBackground,
|
||||
shape = RoundedCornerShape(24.dp)
|
||||
)
|
||||
.padding(vertical = 24.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(16.dp)
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier
|
||||
.align(Alignment.BottomCenter)
|
||||
.fillMaxWidth()
|
||||
.padding(16.dp)
|
||||
.background(
|
||||
color = ExtendedTheme.colors.windowBackground,
|
||||
shape = RoundedCornerShape(24.dp)
|
||||
)
|
||||
.padding(vertical = 24.dp)
|
||||
.clickable(
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
indication = null,
|
||||
onClick = {}
|
||||
),
|
||||
verticalArrangement = Arrangement.spacedBy(16.dp)
|
||||
) {
|
||||
ProvideContentColor(color = ExtendedTheme.colors.text) {
|
||||
if (title != null) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 24.dp)
|
||||
.align(Alignment.CenterHorizontally)
|
||||
) {
|
||||
ProvideTextStyle(value = MaterialTheme.typography.h6.copy(fontWeight = FontWeight.Bold)) {
|
||||
dialogScope.title()
|
||||
}
|
||||
ProvideContentColor(color = ExtendedTheme.colors.text) {
|
||||
if (title != null) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 24.dp)
|
||||
.align(Alignment.CenterHorizontally)
|
||||
) {
|
||||
ProvideTextStyle(value = MaterialTheme.typography.h6.copy(fontWeight = FontWeight.Bold)) {
|
||||
dialogScope.title()
|
||||
}
|
||||
}
|
||||
Box(modifier = Modifier.align(Alignment.CenterHorizontally)) {
|
||||
dialogScope.content()
|
||||
}
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 24.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp)
|
||||
) {
|
||||
dialogScope.buttons()
|
||||
}
|
||||
}
|
||||
Box(modifier = Modifier.align(Alignment.CenterHorizontally)) {
|
||||
dialogScope.content()
|
||||
}
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 24.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp)
|
||||
) {
|
||||
dialogScope.buttons()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -418,11 +423,9 @@ class DialogState private constructor(
|
|||
}
|
||||
|
||||
class DialogScope(
|
||||
private val dialogState: DialogState,
|
||||
private val onDismiss: (() -> Unit)? = null,
|
||||
private val onDismiss: () -> Unit,
|
||||
) {
|
||||
fun dismiss() {
|
||||
onDismiss?.invoke()
|
||||
dialogState.show = false
|
||||
onDismiss()
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,268 @@
|
|||
package com.huanchengfly.tieba.post.ui.widgets.compose.dialogs
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.ContextWrapper
|
||||
import android.view.View
|
||||
import android.view.Window
|
||||
import android.view.WindowManager
|
||||
import androidx.activity.compose.BackHandler
|
||||
import androidx.compose.animation.Animatable
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.animation.slideInHorizontally
|
||||
import androidx.compose.animation.slideInVertically
|
||||
import androidx.compose.animation.slideOutHorizontally
|
||||
import androidx.compose.animation.slideOutVertically
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.gestures.detectTapGestures
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.imePadding
|
||||
import androidx.compose.foundation.layout.systemBarsPadding
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Immutable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.SideEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.input.pointer.pointerInput
|
||||
import androidx.compose.ui.platform.LocalView
|
||||
import androidx.compose.ui.window.Dialog
|
||||
import androidx.compose.ui.window.DialogProperties
|
||||
import androidx.compose.ui.window.DialogWindowProvider
|
||||
import androidx.compose.ui.window.SecureFlagPolicy
|
||||
import androidx.core.view.WindowCompat
|
||||
import kotlinx.coroutines.delay
|
||||
|
||||
|
||||
@Composable
|
||||
fun getDialogWindow(): Window? = (LocalView.current.parent as? DialogWindowProvider)?.window
|
||||
|
||||
@Composable
|
||||
fun getActivityWindow(): Window? = LocalView.current.context.getActivityWindow()
|
||||
|
||||
tailrec fun Context.getActivityWindow(): Window? = when (this) {
|
||||
is Activity -> window
|
||||
is ContextWrapper -> baseContext.getActivityWindow()
|
||||
else -> null
|
||||
}
|
||||
|
||||
private const val DefaultDurationMillis: Int = 250
|
||||
|
||||
@Composable
|
||||
private fun DialogFullScreen(
|
||||
isActiveClose: Boolean,
|
||||
onDismissRequest: () -> Unit,
|
||||
properties: AnyPopDialogProperties,
|
||||
content: @Composable () -> Unit,
|
||||
) {
|
||||
var isAnimateLayout by remember {
|
||||
mutableStateOf(false)
|
||||
}
|
||||
var isBackPress by remember {
|
||||
mutableStateOf(false)
|
||||
}
|
||||
LaunchedEffect(isActiveClose) {
|
||||
if (isActiveClose) {
|
||||
isBackPress = true
|
||||
isAnimateLayout = false
|
||||
}
|
||||
}
|
||||
|
||||
val handleBackPress = {
|
||||
if (!isBackPress) {
|
||||
isBackPress = true
|
||||
isAnimateLayout = false
|
||||
}
|
||||
}
|
||||
|
||||
Dialog(
|
||||
onDismissRequest = onDismissRequest,
|
||||
properties = DialogProperties(
|
||||
// 这里不使用新的测量规范,不能设置为false
|
||||
usePlatformDefaultWidth = true,
|
||||
decorFitsSystemWindows = false,
|
||||
dismissOnBackPress = false,
|
||||
dismissOnClickOutside = false,
|
||||
securePolicy = properties.securePolicy
|
||||
),
|
||||
content = {
|
||||
val animColor = remember { Animatable(Color.Transparent) }
|
||||
LaunchedEffect(isAnimateLayout) {
|
||||
if (properties.backgroundDimEnabled) {
|
||||
animColor.animateTo(
|
||||
if (isAnimateLayout) Color.Black.copy(alpha = 0.45F) else Color.Transparent,
|
||||
animationSpec = tween(properties.durationMillis)
|
||||
)
|
||||
} else {
|
||||
delay(properties.durationMillis.toLong())
|
||||
}
|
||||
if (!isAnimateLayout) {
|
||||
onDismissRequest.invoke()
|
||||
}
|
||||
}
|
||||
val activityWindow = getActivityWindow()
|
||||
val dialogWindow = getDialogWindow()
|
||||
val parentView = LocalView.current.parent as View
|
||||
SideEffect {
|
||||
if (activityWindow != null && dialogWindow != null && !isBackPress && !isAnimateLayout) {
|
||||
val attributes = WindowManager.LayoutParams()
|
||||
attributes.copyFrom(activityWindow.attributes)
|
||||
attributes.type = dialogWindow.attributes.type
|
||||
dialogWindow.attributes = attributes
|
||||
|
||||
dialogWindow.setLayout(
|
||||
activityWindow.decorView.width,
|
||||
activityWindow.decorView.height
|
||||
)
|
||||
WindowCompat.getInsetsController(dialogWindow, parentView)
|
||||
.isAppearanceLightNavigationBars =
|
||||
properties.isAppearanceLightNavigationBars
|
||||
isAnimateLayout = true
|
||||
}
|
||||
}
|
||||
Box(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
contentAlignment = when (properties.direction) {
|
||||
DirectionState.TOP -> Alignment.TopCenter
|
||||
DirectionState.LEFT -> Alignment.CenterStart
|
||||
DirectionState.RIGHT -> Alignment.CenterEnd
|
||||
else -> Alignment.BottomCenter
|
||||
}
|
||||
) {
|
||||
Spacer(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.background(animColor.value)
|
||||
.clickOutSideModifier(
|
||||
dismissOnClickOutside = properties.dismissOnClickOutside,
|
||||
onTap = handleBackPress
|
||||
)
|
||||
)
|
||||
AnimatedVisibility(
|
||||
modifier = Modifier.pointerInput(Unit) {},
|
||||
visible = isAnimateLayout,
|
||||
enter = when (properties.direction) {
|
||||
DirectionState.TOP -> slideInVertically(initialOffsetY = { -it })
|
||||
DirectionState.LEFT -> slideInHorizontally(initialOffsetX = { -it })
|
||||
DirectionState.RIGHT -> slideInHorizontally(initialOffsetX = { it })
|
||||
else -> slideInVertically(initialOffsetY = { it })
|
||||
},
|
||||
exit = when (properties.direction) {
|
||||
DirectionState.TOP -> fadeOut() + slideOutVertically(targetOffsetY = { -it })
|
||||
DirectionState.LEFT -> fadeOut() + slideOutHorizontally(targetOffsetX = { -it })
|
||||
DirectionState.RIGHT -> fadeOut() + slideOutHorizontally(targetOffsetX = { it })
|
||||
else -> fadeOut() + slideOutVertically(targetOffsetY = { it })
|
||||
}
|
||||
) {
|
||||
content()
|
||||
}
|
||||
}
|
||||
BackHandler(enabled = properties.dismissOnBackPress, onBack = handleBackPress)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* @author 被风吹过的夏天
|
||||
* @see <a href="https://github.com/TheMelody/AnyPopDialog-Compose">https://github.com/TheMelody/AnyPopDialog-Compose</a>
|
||||
* @param isActiveClose 设置为true可触发动画关闭Dialog,动画完自动触发[onDismiss]
|
||||
* @param properties Dialog相关配置
|
||||
* @param onDismiss Dialog关闭的回调
|
||||
* @param content 可组合项视图
|
||||
*/
|
||||
@Composable
|
||||
fun AnyPopDialog(
|
||||
onDismiss: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
isActiveClose: Boolean = false,
|
||||
properties: AnyPopDialogProperties = AnyPopDialogProperties(direction = DirectionState.BOTTOM),
|
||||
content: @Composable () -> Unit,
|
||||
) {
|
||||
DialogFullScreen(
|
||||
isActiveClose = isActiveClose,
|
||||
onDismissRequest = onDismiss,
|
||||
properties = properties
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier
|
||||
.systemBarsPadding()
|
||||
.imePadding()
|
||||
) {
|
||||
content()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param dismissOnBackPress 是否支持返回关闭Dialog
|
||||
* @param dismissOnClickOutside 是否支持空白区域点击关闭Dialog
|
||||
* @param isAppearanceLightNavigationBars 导航栏前景色是不是亮色
|
||||
* @param direction 当前对话框弹出的方向
|
||||
* @param backgroundDimEnabled 背景渐入检出开关
|
||||
* @param durationMillis 弹框消失和进入的时长
|
||||
* @param securePolicy 屏幕安全策略
|
||||
*/
|
||||
@Immutable
|
||||
class AnyPopDialogProperties(
|
||||
val direction: DirectionState = DirectionState.BOTTOM,
|
||||
val dismissOnBackPress: Boolean = true,
|
||||
val dismissOnClickOutside: Boolean = true,
|
||||
val isAppearanceLightNavigationBars: Boolean = true,
|
||||
val backgroundDimEnabled: Boolean = true,
|
||||
val durationMillis: Int = DefaultDurationMillis,
|
||||
val securePolicy: SecureFlagPolicy = SecureFlagPolicy.Inherit,
|
||||
) {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other !is AnyPopDialogProperties) return false
|
||||
|
||||
if (dismissOnBackPress != other.dismissOnBackPress) return false
|
||||
if (isAppearanceLightNavigationBars != other.isAppearanceLightNavigationBars) return false
|
||||
if (dismissOnClickOutside != other.dismissOnClickOutside) return false
|
||||
if (direction != other.direction) return false
|
||||
if (backgroundDimEnabled != other.backgroundDimEnabled) return false
|
||||
if (durationMillis != other.durationMillis) return false
|
||||
return securePolicy == other.securePolicy
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = dismissOnBackPress.hashCode()
|
||||
result = 31 * result + dismissOnClickOutside.hashCode()
|
||||
result = 31 * result + isAppearanceLightNavigationBars.hashCode()
|
||||
result = 31 * result + direction.hashCode()
|
||||
result = 31 * result + backgroundDimEnabled.hashCode()
|
||||
result = 31 * result + durationMillis.hashCode()
|
||||
result = 31 * result + securePolicy.hashCode()
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
enum class DirectionState {
|
||||
TOP,
|
||||
LEFT,
|
||||
RIGHT,
|
||||
BOTTOM
|
||||
}
|
||||
|
||||
private fun Modifier.clickOutSideModifier(
|
||||
dismissOnClickOutside: Boolean,
|
||||
onTap: () -> Unit,
|
||||
) = this.then(
|
||||
if (dismissOnClickOutside) {
|
||||
Modifier.pointerInput(Unit) {
|
||||
detectTapGestures(onTap = {
|
||||
onTap()
|
||||
})
|
||||
}
|
||||
} else Modifier
|
||||
)
|
||||
Loading…
Reference in New Issue