常用命令式的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()
}
}
代码比较简单,便不赘诉。
预览