pop
pop
Published on 2024-12-17 / 131 Visits
0
0

Compose支持背景模糊的XDialog

常用命令式的Android开发中,我们使用通过控制window的背景实现模糊。尤其Android12以后,Google官方支持了高斯模糊,应用实现模糊效果更加方便。

但是在Compose的Android开发中,官方并没有支持模糊效果。从GitHub仓库获得灵感,如果你的应用支持Android12以上,那么可以使用本帖中的代码快速实现高斯模糊效果。

import android.view.Gravity
import android.view.WindowManager
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
import androidx.compose.ui.window.DialogWindowProvider
​
/**
 * Dialog - Support Blur
 * @param gravity window gravity in wrapper
 * @param offset offset from gravity
 * @param windowDimAmount behind window dimAmount
 * @param behindBlurRadius behind window blur radius
 * @param contentBlurRadius dialog window blur radius
 * @param onDismissRequest Executes when the user tries to dismiss the dialog.
 * @param extraFlags customized flags add to window
 * @param properties [DialogProperties] for further customization of this dialog's behavior.
 * @param content The content to be displayed inside the dialog.
 */
@Composable
fun XBlurDialog(
    gravity: Int = Gravity.CENTER,
    offset: IntOffset = IntOffset(0, 0),
    windowDimAmount: Float? = null,
    behindBlurRadius: Int? = null,
    contentBlurRadius: Int? = null,
    onDismissRequest: () -> Unit = {},
    vararg extraFlags: Int = intArrayOf(),
    properties: DialogProperties = DialogProperties(
        usePlatformDefaultWidth = false,
        dismissOnClickOutside = false,
        dismissOnBackPress = false
    ),
    content: @Composable () -> Unit
) {
    Dialog(
        onDismissRequest = onDismissRequest,
        properties = properties,
    ) {
​
        val dialogWindowProvider = LocalView.current.parent as DialogWindowProvider
        val window = dialogWindowProvider.window
​
        window.setGravity(gravity)
​
        window.attributes.apply {
            x = offset.x
            y = offset.y
        }
​
        windowDimAmount?.run {
            window.setDimAmount(this)
            window.setFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND, WindowManager.LayoutParams.FLAG_BLUR_BEHIND)
            behindBlurRadius?.let { window.attributes.blurBehindRadius = it }
​
        } ?: window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
​
        extraFlags.forEach {
            window.addFlags(it)
        }
​
        contentBlurRadius?.run { window.setBackgroundBlurRadius(this) }
​
        content()
​
    }
}

代码比较简单,便不赘诉。

预览


Comment