【笔记】安卓毛玻璃效果(Blur)实现笔记(使用BlurView)(结尾附:源码)

由于业务开发需要一个毛玻璃的效果,现AI发展如此迅速,这些效果AI都可完成。故本文仅作纯文本记录。
特别说明:下图为AI生成,由于无法使用实际业务截图,故采用AI生成示例图。

安卓毛玻璃效果(Blur)实现笔记(使用BlurView)

本文只聚焦一个问题:如何在 Android 中实现"毛玻璃背景效果"。内容围绕实际项目落地,总结实现方式、三方库使用方法以及关键避坑点。

1.毛玻璃的本质

很多实现中容易把"半透明黑色背景"误认为毛玻璃效果。实际上两者完全不同。毛玻璃的核心在于对背景内容进行模糊处理,再叠加一层透明蒙层,从而既保留背景的结构感,又降低视觉干扰。

从实现角度看,本质流程可以概括为:先获取背景内容,将其进行模糊处理,然后再叠加一层透明度适中的遮罩层。如果缺少模糊步骤,仅使用透明黑色,只会得到压暗效果,不具备毛玻璃的通透质感。

2.实现方案选择

Android 上实现毛玻璃主要有两种方式:一种是基于系统能力的原生实现,另一种是借助第三方库。

RenderEffect 是 Android 12 引入的原生模糊能力,性能表现较好,但它只能对当前 View 自身内容进行处理,无法直接对"背后内容"进行模糊,因此在弹窗、遮罩层这类场景中不适用。

java 复制代码
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
    view.setRenderEffect(
        RenderEffect.createBlurEffect(20f, 20f, Shader.TileMode.CLAMP)
    );
}

实际开发中更推荐使用 BlurView。该库的核心优势在于可以对目标 View 进行离屏渲染后再进行模糊处理,从而实现对"底层内容"的模糊效果,适合绝大多数 UI 场景。

Dimezis/BlurView

build.gradle 复制代码
implementation 'com.github.Dimezis:BlurView:version-2.0.6'

3.使用BlurView

BlurView 的核心原理

理解 BlurView 的工作机制非常重要。BlurView 并不是对自身做模糊,而是通过指定一个目标 View,将该 View 渲染到离屏缓冲区,然后对其进行模糊处理,最后再绘制到当前视图中。

因此,BlurView 的效果完全取决于它绑定的 targetView。如果 targetView 选择错误,即使代码正确也无法得到预期效果。

BlurView 使用方式

BlurView 的关键在于 setupWith 方法。这个方法的参数必须是"需要被模糊的背景容器"。

正确写法是将 BlurView 绑定到一个独立的内容层,而不是绑定自身。如果将 BlurView 作为 targetView 传入,本质上等于对自身进行模糊,这种写法不会产生任何有效结果。

因此,在实际开发中必须明确一点:BlurView 负责显示模糊结果,targetView 才是被模糊的数据来源。

布局结构设计

毛玻璃效果能否正常显示,很大程度取决于布局结构。推荐采用三层结构。

最底层是内容层,也就是需要被模糊的部分,例如背景图、列表或页面主体。中间层是 BlurView,用于显示模糊后的结果。最上层是前景 UI,例如按钮、文字或弹窗内容。

这种分层方式能够保证模糊效果只作用于背景,同时前景内容保持清晰。如果将所有元素混在同一层级中,BlurView 无法正确获取目标内容,效果会异常。

初始化流程

在初始化时,需要完成三个关键步骤:绑定 targetView、设置模糊半径以及设置蒙层颜色。

绑定 targetView 时建议传入页面中专门用于承载背景内容的容器,同时配合 windowBackground 作为清屏背景,避免出现闪烁或残影。

模糊半径建议控制在合理范围内。过小会导致效果不明显,过大则会带来性能开销和画面过度模糊的问题。一般推荐在 15 到 18 之间进行调节。

蒙层颜色用于控制视觉层级。透明度越高,背景越暗,通透感越弱。透明度越低,则更接近原始背景。实际项目中通常选择中等透明度,以兼顾可读性与美观性。

java 复制代码
BlurView blurView = findViewById(R.id.blur_view);
ViewGroup targetView = findViewById(R.id.content_target);

Drawable windowBackground = getWindow().getDecorView().getBackground();

blurView.setupWith(targetView)
        .setFrameClearDrawable(windowBackground)
        .setBlurRadius(18f);

blurView.setOverlayColor(Color.parseColor("#4D000000"));

参数调优要点

模糊半径和蒙层透明度是影响视觉效果的两个核心参数。两者需要配合调整,而不是单独调节。

如果模糊半径较大,同时蒙层透明度也较高,就会出现"整体发黑"的问题。相反,如果模糊较轻但蒙层过低,则背景干扰较强。

推荐的实践是优先控制模糊半径在中等范围,再通过调整蒙层透明度来达到视觉平衡。

另外,setFrameClearDrawable 虽然不是必选项,但在大多数情况下建议设置。它可以在绘制前提供一个基础背景,避免出现透明区域闪烁或残影问题。

  • 模糊半径
效果
轻模糊 12 ~ 15
标准 15 ~ 18
强模糊 20+
  • 黑色透明蒙层
透明度
20% #33000000
30% #4D000000
40% #66000000
60% #99000000(偏黑)
  • 补充背景
java 复制代码
.setFrameClearDrawable(windowBackground)

作用:

防止黑屏 / 残影

补充背景

推荐始终设置

常见问题与原因分析

毛玻璃效果未生效,最常见的原因是 targetView 传错,尤其是将 BlurView 自身作为目标。这种情况下不会有任何模糊效果。

如果只看到黑色遮罩而没有模糊,通常是蒙层透明度过高,或者 targetView 本身没有有效内容。例如背景为纯色时,模糊后仍然是纯色。

还有一个重要限制是,某些特殊渲染组件无法被 BlurView 捕获,例如 SurfaceView、GLSurfaceView 或部分视频渲染层。这类组件不参与普通 View 的绘制流程,因此无法被离屏渲染获取。

性能问题通常出现在模糊半径过大或目标 View 结构复杂的情况下。此时应适当降低模糊强度,并减少 targetView 的绘制复杂度。

在弹层场景中,还需要注意避免重复初始化 BlurView。可以通过状态标记控制只在首次显示时进行 setupWith 调用。

4.实践总结

在实际项目中,实现毛玻璃效果的关键并不在于使用哪个库,而在于是否正确理解渲染关系。BlurView 只是工具,真正决定效果的是 targetView 的选择、布局层级的划分以及参数的合理配置。

一个稳定且通用的实现方式,是将页面内容拆分为独立的背景层和前景层,使用 BlurView 对背景层进行模糊处理,并通过适中的透明蒙层控制视觉效果。

复制代码
第一层:被模糊内容层
	放普通背景、普通控件。
	
第二层:VIP 毛玻璃遮罩层
	放 GlassBlurView和遮罩上方需要显示的内容

第三层:顶层固定按钮

从经验来看,只要满足三个条件,毛玻璃效果基本可以稳定落地:targetView 正确、模糊半径合理、蒙层透明度适中。

最终效果的好坏,往往取决于细节调优,而不是代码复杂度。

附:

java 复制代码
public class GlassBlurView extends FrameLayout {

    private BlurView blurView;

    public GlassBlurView(@NonNull Context context) {
        super(context);
        init(context);
    }

    public GlassBlurView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public GlassBlurView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    private void init(Context context) {
        blurView = new BlurView(context);
        LayoutParams params = new LayoutParams(
                LayoutParams.MATCH_PARENT,
                LayoutParams.MATCH_PARENT
        );
        addView(blurView, params);
        blurView.setOverlayColor(Color.parseColor("#99000000"));
    }

    public void setupWithTarget(@NonNull ViewGroup targetView, @Nullable Drawable windowBackground) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            blurView.setupWith(targetView, new RenderEffectBlur())
                    .setFrameClearDrawable(windowBackground)
                    .setBlurRadius(20f);
        } else {
            blurView.setupWith(targetView, new RenderScriptBlur(getContext()))
                    .setFrameClearDrawable(windowBackground)
                    .setBlurRadius(20f);
        }
    }

    public void setBlurRadius(float radius) {
        blurView.setBlurRadius(radius);
    }

    public void setOverlayColor(String colorString) {
        blurView.setOverlayColor(Color.parseColor(colorString));
    }

    public BlurView getInnerBlurView() {
        return blurView;
    }
}
  • 使用
java 复制代码
GlassBlurView glassBlurView = findViewById(R.id.glass_blur_view);
ViewGroup targetView = findViewById(R.id.content_target);
Drawable windowBackground = getWindow().getDecorView().getBackground();

glassBlurView.setupWithTarget(targetView, windowBackground);
glassBlurView.setBlurRadius(20f);
glassBlurView.setOverlayColor("#99000000");
xml 复制代码
<GlassBlurView
    android:id="@+id/glass_blur_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>
相关推荐
zore_c2 小时前
【C++】C++——类的默认成员函数(构造、析构、拷贝构造函数)
java·c语言·c++·笔记·算法·排序算法
StackNoOverflow4 小时前
MySQL Explain 返回列详解:从入门到实战,附 SQL 与避坑大全
android
夜瞬10 小时前
NLP学习笔记01:文本预处理详解——从清洗、分词到词性标注
笔记·学习·自然语言处理
中屹指纹浏览器10 小时前
指纹浏览器内核级渲染伪造技术:Canvas/WebGL/AudioContext深度伪造与检测绕过实战
经验分享·笔记
-Springer-11 小时前
STM32 学习 —— 个人学习笔记11-1(SPI 通信协议及 W25Q64 简介 & 软件 SPI 读写 W25Q64)
笔记·stm32·学习
LN花开富贵11 小时前
【ROS】鱼香ROS2学习笔记一
linux·笔记·python·学习·嵌入式·ros·agv
CYRUS_STUDIO12 小时前
Frida 检测与对抗实战:进程、maps、线程、符号全特征清除
android·逆向
IT199512 小时前
Wireshark笔记-对AI连接标准MCP抓包分析
笔记·测试工具·wireshark
csj5013 小时前
安卓基础之《(28)—Service组件》
android