官方指导:source.android.google.cn/docs/core/d…
注意:仅支持Android 12及以上平台
1. 使用方法
1.1 模糊当前窗口背景
- 设置窗口半透明:主题中
windowIsTranslucent设置为true - 设置模糊半径:主题中
backgroundBlurRadius设置为非0,Window也有相应方法setBackgroundBlurRadius- 取值范围(0, 150)
- 典型数值 20 即可达到一般模糊效果,80可达到高斯模糊效果
- 数值越大,性能越差
- 设置窗口背景透明:主题或者代码中设置
windowBackground为带透明度的颜色或者Drawable- 通过带圆角和透明度的
ShapeDrawable可以支持带圆角的窗口
- 通过带圆角和透明度的
1.2 模糊当前窗口后面整个屏幕
- 使能模糊:主题中
windowBlurBehindEnabled设置为true或 窗口添加FLAG_BLUR_BEHIND - 设置模糊半径:主题中
windowBlurBehindRadius设置为非0,Window.LayoutParams也有相应方法setBlurBehindRadius- 取值范围(0, 150)
- 典型数值 20 即可达到一般模糊效果,80可达到高斯模糊效果
- 数值越大,性能越差
- 还可以设置背景屏幕变暗(可选):
- 使能背景变暗:主题中
backgroundDimEnabled设置为true或窗口添加FLAG_DIM_BEHIND - 设置变暗程度:主题中
dimAmount设置为 0 - 1 的浮点数,越大越不透明,Window也有相应方法setDimAmount
- 使能背景变暗:主题中
- 显示出被窗口覆盖区域的内容(可选):主题中
windowIsTranslucent设置为true,使窗口半透明- 设置透明窗口背景:主题或者代码中设置
windowBackground为带透明度的颜色或者Drawable
- 设置透明窗口背景:主题或者代码中设置
以上两种方式可以同时使用
1.3 监听窗口模糊开关变化
窗口模糊在运行时可能会被禁用,比如用户操作或者省电模式,可以通过 WindowManager 中的接口监听变化和查看状态
// Add listener
void addCrossWindowBlurEnabledListener(Consumer<Boolean> listener)
// Remove listener
void removeCrossWindowBlurEnabledListener(Consumer<Boolean> listener)
// Get the blur enable state
boolean isCrossWindowBlurEnabled()
2. 模糊实现机制简介
基于Android 14 源码
2.1 模糊当前窗口背景
实现主要分为两部分:设置参数和图像合成,图像合成单列出来说明 设置参数主要涉及到的类:
- PhoneWindow
- DecorView
- BackgroundBlurDrawable
- ViewRootImpl
- SurfaceControl
- SurfaceComposeClient
- SurfaceFlinger
2.2 模糊当前窗口后面整个屏幕
实现主要分为两部分:设置参数和图像合成,图像合成单列出来说明 设置参数主要涉及到的类:
- WindowManagerService
- WindowState
- Dimmer
- SurfaceControl
- SurfaceComposeClient
- SurfaceFlinger
2.3 图像合成
前面 2.1/2.2 分别将blur相关信息传到SurfaceFlinger,在下一帧图像合成时就会包含模糊图形 合成主要涉及的类:
- SurfaceFlinger
- CompositionEngine
- Display/Output
- RenderEngine
- SkiaRenderEngine
- BlurFilter
在 drawLayersInternal 中会从后往前将每一个需要合成的 Layer 绘制到Buffer中,模糊相关的请搜索 BlurFilter