官方指导: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