Android 弹窗毛玻璃背景实践

需求: 点击FloatingActionButton弹出弹层,弹层底部有多个图标可选,每一个图标都是一个功能入口,背景采用毛玻璃模糊效果。

记录一下这个需求的思考和实现过程。

查找Android原生API做法

在Android API里面,有个FLAG_BLUR_BEHIND用于模糊背景的FLAG,尝试一下使用它来做Dialog的背景模糊。 代码如下:

final Dialog dialog = new Dialog(MainActivity.this, R.style.SquareEntranceDialogStyle);

Window window = dialog.getWindow();

if (window != null) {

window.setFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND,

WindowManager.LayoutParams.FLAG_BLUR_BEHIND);

window.setGravity(Gravity.BOTTOM);

}

View layout = View.inflate(MainActivity.this, R.layout.square_posting_entrance_dialog, null);

dialog.setContentView(layout);

dialog.show();复制代码

true

true

@android:color/transparent

复制代码

最后出来的效果有点迷。在4.4的机器上,看不出任何模糊效果,而在7.0的机器上,dialog的弹窗背景出现了一片灰色,而遮罩层的效果没有任何变化。 查看了源码,发现这个FLAG已经在4.1以后就废弃了。

通过高斯模糊把处理后的图片作为弹层背景

换了一种思路,把遮罩模糊拆成了几个步骤来实现

把dialog弹层铺满整个屏幕

通过应用内截图的方式获得弹层背后的图片bitmap

通过高斯模糊算法对截图进行模糊处理

把模糊后的图片bitmap设置成dialog的background

把问题拆开以后,单独实现每一个步骤就容易多了。

1.把dialog弹层铺满整个屏幕:

在拆分问题的一开始,我的思路是怎么去更改dialog的遮罩层颜色,或者把遮罩层整体设置成图片,但尝试了多种方法都无法实现,最后在stackoverflow查到了另一种思路,把dialog铺满屏幕,然后修改dialog的windowBackground来达到跟修改遮罩层相同的效果。

通过修改dialog style的windowIsFloating为false,可以使dialog铺满屏幕

true

false

@android:color/transparent

复制代码

把dialog的根布局改成match_parent,并加上一点白色背景色和透明度

xmlns:tool="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:background="#ebebeb"

android:alpha="0.8"

android:gravity="center_horizontal|bottom">

...

复制代码

2.通过应用内截图的方式获得弹层背后的图片bitmap

通过activity的window.getDecorView()获取到窗口最顶层的view,然后开启Cache机制使View可以保存成Bitmap,在每次获取View截图前通过destroyDrawingCache()先清除上一次的旧缓存,然后通过buildDrawingCache()重新生成一张最新截图,最后通过getDrawingCache()获取截图Bitmap

View activityView = getWindow().getDecorView();

activityView.setDrawingCacheEnabled(true);

activityView.destroyDrawingCache();

activityView.buildDrawingCache();

Bitmap bmp = activityView.getDrawingCache();复制代码

3.通过高斯模糊算法对截图进行模糊处理

高斯模糊算法直接搜索了一个封装好了的工具类,通过RenderScript进行模糊处理

public class BlurBitmap {

/**

* 图片缩放比例

*/

private static final float BITMAP_SCALE = 0.4f;

/**

* 最大模糊度(在0.0到25.0之间)

*/

private static final float BLUR_RADIUS = 15f;

/**

* 模糊图片的具体方法

*

* @param context 上下文对象

* @param image 需要模糊的图片

* @return 模糊处理后的图片

*/

public static Bitmap blur(Context context, Bitmap image) {

// 计算图片缩小后的长宽

int width = Math.round(image.getWidth() * BITMAP_SCALE);

int height = Math.round(image.getHeight() * BITMAP_SCALE);

// 将缩小后的图片做为预渲染的图片。

Bitmap inputBitmap = Bitmap.createScaledBitmap(image, width, height, false);

// 创建一张渲染后的输出图片。

Bitmap outputBitmap = Bitmap.createBitmap(inputBitmap);

// 创建RenderScript内核对象

RenderScript rs = RenderScript.create(context);

// 创建一个模糊效果的RenderScript的工具对象

ScriptIntrinsicBlur blurScript = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));

// 由于RenderScript并没有使用VM来分配内存,所以需要使用Allocation类来创建和分配内存空间。

// 创建Allocation对象的时候其实内存是空的,需要使用copyTo()将数据填充进去。

Allocation tmpIn = Allocation.createFromBitmap(rs, inputBitmap);

Allocation tmpOut = Allocation.createFromBitmap(rs, outputBitmap);

// 设置渲染的模糊程度, 25f是最大模糊度

blurScript.setRadius(BLUR_RADIUS);

// 设置blurScript对象的输入内存

blurScript.setInput(tmpIn);

// 将输出数据保存到输出内存中

blurScript.forEach(tmpOut);

// 将数据填充到Allocation中

tmpOut.copyTo(outputBitmap);

return outputBitmap;

}

}复制代码

4.把模糊后的图片bitmap设置成dialog的background

最后获取到模糊处理后的bitmap,设置到dialog的windowBackground中,即可做出弹层模糊背景的效果,完整代码如下:

final Dialog dialog = new Dialog(MainActivity.this, R.style.SquareEntranceDialogStyle);

Window window = dialog.getWindow();

Bitmap blurBg = null;

if (window != null) {

long startMs = System.currentTimeMillis();

// 获取截图

View activityView = getWindow().getDecorView();

activityView.setDrawingCacheEnabled(true);

activityView.destroyDrawingCache();

activityView.buildDrawingCache();

Bitmap bmp = activityView.getDrawingCache();

Log.d(TAG, "getDrawingCache take away:" + (System.currentTimeMillis() - startMs) + "ms");

// 模糊处理并保存

blurBg = BlurBitmap.blur(MainActivity.this, bmp);

Log.d(TAG, "blur take away:" + (System.currentTimeMillis() - startMs) + "ms");

// 设置成dialog的背景

window.setBackgroundDrawable(new BitmapDrawable(getResources(), blurBg));

bmp.recycle();

}

final Bitmap finalBlurBg = blurBg;

dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {

@Override

public void onDismiss(DialogInterface dialog) {

// 对话框取消时释放背景图bitmap

if (finalBlurBg != null && !finalBlurBg.isRecycled()) {

finalBlurBg.recycle();

}

}

});

View layout = View.inflate(MainActivity.this, R.layout.square_posting_entrance_dialog, null);

dialog.setContentView(layout);

dialog.show();复制代码

通过打Log检测获取截图以及模糊处理所要消耗的时间,总处理时长大概在50~80ms,还算可以,没有出现卡顿的情况。

最后补一张效果图

android 玻璃背景,Android 弹窗毛玻璃背景实践相关推荐

  1. Android 10.0 Launcher3双层(抽屉)高斯模糊(毛玻璃)背景功能的实现

    1.概述 在进行定制开发的功能需求方面,Launcher3的需求也挺多的,单双层抽屉高斯模糊毛玻璃背景功能也是一个需求功能,最近按照功能需求来开发 双层抽屉高斯模糊毛玻璃效果背景的功能 效果图如图: ...

  2. Android 抽屉菜单滑动时模糊背景 | 毛玻璃效果

    先来看看要实现的效果图 录制的有点模糊在补一张静态图 简单的分析一下: 1⃣️一开始我一直以为抽屉菜单的背景是一张半透明的高斯模糊图片,一直尝试着用ps做一张然后发现并没有什么卵用(纯色背景或者图片是 ...

  3. Android中使用xml处理图片,Android布局 – 在xml中偏移背景图像

    我有一个大的png,我想用它作为不同布局的背景,但是偏移它以便我可以有不同的部分显示(很像你可以在CSS中),最好是在xml中. 我的活动主要布局包含以下xml: android:layout_wid ...

  4. Android实现仿QQ登录界面背景动画效果

    登录QQ的时候,我们会看到在登录界面的背景不是静态的,而是一段动画效果,刚开始觉得蛮好奇的,现在我们也来实现一下这种效果,实现起来还是挺简单的. 实现步骤: 1.自定义CustomVideoView类 ...

  5. 自定义android控件EditText 自定义边框 背景

    自定义EditText边框背景: 首先重新定义一个style.在values文件夹下新建一个xml文件: <?xml version="1.0" encoding=" ...

  6. Android App自适应draw9patch不失真背景

    做人要大度,海纳百川,做事要圆滑,左右逢源,这让我想到了编程也是如此,代码要扩展,界面也要考虑自适应. 这篇文章是android开发人员的必备知识,是我特别为大家整理和总结的,不求完美,但是有用. 1 ...

  7. android 自定义皮肤,Android Studio 自定义皮肤主题和背景

    新的一年,新的开始,在这里先祝福大家在新的一年收获多多,多升职,多加薪,代码没BUG. 第一 Android Studio自定义皮肤主题-ColorThemes 寒假期间有人问我, "你代码 ...

  8. Android ImageView图片显示点击背景切换

    为什么80%的码农都做不了架构师?>>>    一.介绍 ImageView用来显示任意图像图片,可以自己定义显示尺寸,显示颜色等等. 二.XML属性 android:adjustV ...

  9. android popupwindow 自定义背景,android – 无法将PopupWindow背景设置为透明

    我有以下代码: View child = getLayoutInflater().inflate(R.layout.contextual_menu_lp_activity,null) child.se ...

  10. 自定义背景android,Android自定义Button并设置不同背景图片的方法

    本文实例讲述了Android自定义Button并设置不同背景图片的方法.分享给大家供大家参考,具体如下: 1.自定义MyButton类 public class MyButton extends Bu ...

最新文章

  1. Matlab与线性代数 -- 均匀分布的随机矩阵
  2. 腾讯云工业互联网助力平台发布 推动制造业“数字化”蝶变
  3. winpython使用教程-Win系统PyQt5安装和使用教程
  4. arm linux 识别新硬盘_Arm发布首款64位实时处理器CortexR82
  5. java程序运存扩容
  6. Linux 运行进程实时监控pidstat命令详解
  7. 【转】【翻译】实体框架中的POCO支持 - 第二部分 - 复杂类型,延迟装载和显式装载...
  8. 【转】01.Dicom 学习笔记-DICOM C-Store 消息服务
  9. springboot使用spring-data-jpa操作MySQL数据库
  10. 在计算机网络应用发展过程中 被称为,计算机网络技术与应用第三章考试题
  11. R语言使用table1包绘制(生成)三线表、使用单变量分列构建三线表、编写自定义三线表结构(将因子变量细粒度化重新构建三线图)、自定义修改描述性统计参数输出自定义统计量
  12. Bilibili缓存视频在电脑端直接打开方式
  13. EPON联通网关超级管理员密码获取办法
  14. python 小海龟 教案_幼儿园小班健康活动《勇敢的小海龟》教案
  15. 飞桨博士会第十一期回顾:人工智能与生命科学的硬核碰撞
  16. 【SNA】社会网络分析二 Gephi 功能详解
  17. ubuntu文件夹右键没有共享选项
  18. PMP工具与技术之人际关系与团队技能
  19. TOEFL wordlist 14
  20. mysql语句统计总数_一条sql语句实现统计查询_MySQL

热门文章

  1. 哪些行业网站适合使用CDN加速?
  2. TortoiseSVN常见用法
  3. 管理计算机找不到应用程序,电脑打开IE浏览器显示找不到应用程序如何解决
  4. CTF 内存取证 USB流量分析
  5. bin文件夹和lib文件夹
  6. 支持跨平台的移动开发工具大盘点!
  7. 独家专访阿里云存储负责人吴结生:我经历的三个重大决策
  8. C语言实现系统日历查询系统
  9. webstorm最新版激活破解
  10. CSP—— 登机牌条码(多项式的求解以及多项式的除法)