Android实现高斯模糊的效果网上能搜索到很多,但是关于多任务列表高斯模糊处理的文章缺比较少,这里简单记录一下我自己的实现过程,虽然有些瑕疵,但是思路最重要,记录一下。关于这个瑕疵,也会在接下来正文里有介绍。

先上一张MIUI11下的多任务预览图模糊的效果,要实现这个效果,首先要确定具体的实现思路,我的思路分为以下四步:

1 监听多任务按键事件,Android中,返回键的监听可以通过重写onBackPressed或者拦截按键点击事件来实现。但是对于多任务键的监听比较特殊,无法通过按键拦截来实现监听(至少我的小米手机上是这样的),但是我们可以通过广播来监听多任务键。先贴一下代码吧

 /*** 参数*/private static final String SYSTEM_REASON = "reason";private static final String SYSTEM_HOME_RECENT_APPS = "recentapps";private Context mContext;private BroadcastReceiver mDeviceKeyReceiver = null;private OnKeyListener mListener;public DeviceKeyMonitor (Context context, final OnKeyListener listener) {mContext = context;mListener = listener;mDeviceKeyReceiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {String action=intent.getAction();if(!TextUtils.isEmpty(action)){if (intent.getAction().equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) {String reason = intent.getStringExtra(SYSTEM_REASON);if (reason == null)return;// 最近任务列表键if (reason.equals(SYSTEM_HOME_RECENT_APPS)) {mListener.onRecentClick();}}}}};mContext.registerReceiver(mDeviceKeyReceiver, new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));}public interface OnKeyListener{void onRecentClick();//多任务键监听}public void unregister(){if (mDeviceKeyReceiver != null){mContext.unregisterReceiver(mDeviceKeyReceiver);mDeviceKeyReceiver = null;}}

然后在activity中重写onRecentClick事件。

2 第二步就是对当前activity截图,核心代码如下

/**** 截取当前activity* @param activity* @return*/public static Bitmap activityShot(Activity activity) {/*获取windows中最顶层的view*/View view = activity.getWindow().getDecorView();//允许当前窗口保存缓存信息view.setDrawingCacheEnabled(true);view.buildDrawingCache();//获取状态栏高度Rect rect = new Rect();view.getWindowVisibleDisplayFrame(rect);int statusBarHeight = rect.top;WindowManager windowManager = activity.getWindowManager();//获取屏幕宽和高DisplayMetrics outMetrics = new DisplayMetrics();windowManager.getDefaultDisplay().getMetrics(outMetrics);int width = outMetrics.widthPixels;int height = outMetrics.heightPixels;//去掉状态栏Bitmap bitmap = Bitmap.createBitmap(view.getDrawingCache(), 0, statusBarHeight, width,height - statusBarHeight);//销毁缓存信息view.destroyDrawingCache();view.setDrawingCacheEnabled(false);return bitmap;}

方法返回的bitmap就是我们截取activity之后的bitmap。

3 第三步,将截取的activity高斯模糊处理。关于高斯模糊,在Android中常用的高斯模糊技术有三种RenderScript 、fastBlur对RenderScript和fastBlur的优化。由于本文使用的高斯模糊框架是RenderScript,所以这里简单介绍一下RenderScript,其他两种方式的详细介绍网上有大量的文章可以参考。

RenderScript是在Android上的高性能运行密集型运算的框架,RenderScript主要用于数据并行计算,尤其对图像处理、摄影分析和计算机视觉特别有用。RenderScript是在Android3.0(API 11)引入的。而Android图片高斯模糊处理,通常也是用这个库来完成。它提供了我们Java层调用的API,实际上是在c/c++ 层来处理的,所以它的效率和性能通常是最高的。要使用RenderScript完成图片高斯模糊只需要以下几步:

(1) 初始化一个RenderScript Context:RenderScript 上下文环境通过create(Context)方法来创建,它保证RenderScript的使用并且提供一个控制后续所有RenderScript对象(如:ScriptIntrinsicBlur、Allocation等)生命周期的对象。

(2)通过Script至少创建一个Allocation:一个Allocation是提供存储大量可变数据的RenderScript 对象。在内核中,Allocation作为输入和输出,在内核中通过rsGetElementAt_type ()和rsSetElementAt_type()方法来访问Allocation当script全局绑定的时候。使用createFromBitmap 和createTyped来创建Allocation。

(3)创建ScriptIntrinsic:它内置了RenderScript 的一些通用操作,如高斯模糊、扭曲变换、图像混合等等,更多的操作请看ScriptIntrinsic的子类,本文要用的高斯模糊处理就是用的它的子类ScriptIntrinsicBlur。
(4)填充数据到Allocations:除了使用方法createFromBitmap创建的Allocation外,其它的第一次创建时都是填充的空数据。

(5)** 设置模糊半径**:设置一个模糊的半径,其值为 0-25。

(6) 启动内核,调用方法处理:调用forEach 方法模糊处理。

(7) ** 从Allocation 中拷贝数据**:为了能在Java层访问Allocation的数据,用Allocation其中一个copy方法来拷贝数据。
(8) 销毁RenderScript对象:可以用destroy方法来销毁RenderScript对象或者让它可以被垃圾回收,destroy 之后,就能在用它控制的RenderScript对象了(比如在销毁了之后,再调用ScriptIntrinsic或者Allocation的方法是要抛异常的)。

对应的核心代码如下

public static Bitmap rsBlur(Context context, Bitmap source, int radius){Bitmap inputBmp = source;//(1)//初始化一个RenderScript ContextRenderScript renderScript =  RenderScript.create(context);//        Log.i(TAG,"setDrawingCacheEnabledle size:"+inputBmp.getWidth()+"*"+inputBmp.getHeight());// Allocate memory for Renderscript to work with//(2)//创建输入输出的allocationfinal Allocation input = Allocation.createFromBitmap(renderScript,inputBmp);final Allocation output = Allocation.createTyped(renderScript,input.getType());//(3)// Load up an instance of the specific script that we want to use.//创建ScriptIntrinsicScriptIntrinsicBlur scriptIntrinsicBlur = ScriptIntrinsicBlur.create(renderScript, Element.U8_4(renderScript));//(4)//填充数据scriptIntrinsicBlur.setInput(input);//(5)// Set the blur radius//设置模糊半径scriptIntrinsicBlur.setRadius(radius);//(6)// Start the ScriptIntrinisicBlur//启动内核scriptIntrinsicBlur.forEach(output);//(7)// Copy the output to the blurred bitmap//copy数据output.copyTo(inputBmp);//(8)//销毁renderScriptrenderScript.destroy();return inputBmp;}

4 第四步,将高斯模糊处理之后的bitmap填充到activity的根布局中,在这之前先简单介绍一下activity的布局结构图

这是从网上找的一张图,通过这张图可以看到,每个activity都包含一个Window对象,在Android中的window对象其实就是PhoneWindow。PhoneWindow内部又包含一个DecorView,这个DecorView就是整个activity的根布局。所以要将模糊处理之后的bitmap填充到整个activity中就需要在decoriew中做手脚。

因为的decorview本身就是一个FrameLayout,我们可以在decorview中创建一个imageview,然后将处理后的图片填充到imageview中去。核心代码如下

@Overridepublic void onRecentClick() {
//        Toast.makeText(this,"按了多任务键",Toast.LENGTH_LONG).show();
//      group = (ViewGroup) this.getWindow().getDecorView();group.removeView(imageView);
//      创建imageviewimageView = new ImageView(this);FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);imageView.setLayoutParams(params);//      截图,并将图片高斯模糊处理Bitmap bitmap=PicUtil.rsBlur(GaussianBlurActivity.this,PicUtil.activityShot(GaussianBlurActivity.this),20);
//      将处理后的图片填充到imageviewimageView.setImageBitmap(bitmap);group.addView(imageView);}

5 第五步,退出多任务模式时将界面的imageview删除

@Overrideprotected void onResume() {super.onResume();for(int i=0;i<group.getChildCount();i++){group.removeView(imageView);}}

贴上最终效果:

前文说过,按照这个思路实现的效果是有瑕疵的,具体的表现就是,当按下多任务键的时候有时候会先出现模糊效果,然后模糊效果又消失了,猜测是和广播发送和接收的时机有关,具体原因有待进一步研究。

android多任务列表高斯模糊相关推荐

  1. android 多任务按钮,XDA大神推出Android多任务切换神器

    Android设备都会有专用的按钮来查看和切换多任务列表,例如通过长按Home键来实现.现在切换多任务有了更炫的方式.<Switchr>是一款Android上的多任务切换软件,使用了它之后 ...

  2. android倒计时功能,Android 实现列表倒计时功能

    Android 实现列表倒计时功能 发布时间:2020-08-21 21:47:11 来源:脚本之家 阅读:147 作者:Choi晨 单个计时器,然后遍历数据 刷新条目: 两种实现方式:1.Handl ...

  3. android优美列表页面,android listview 列表 点击列表进入详细页面

    [实例简介] android listview 列表 点击列表进入详细页面 [实例截图] [核心代码] ListviewSingleChoice └── ListviewSingleChoice ├─ ...

  4. android开发列表界面

    android开发列表界面,上边是一个显示题目,下边显示的是图标,中间显示的是列表. 看一下效果吧 当鼠标点击上之后出现背景图,下面看一下如何做出这样的效果吧. 1.创建android工程 修改mai ...

  5. (转)Android权限列表permission说明 (一)

    网络上不乏android权限列表,但是很少有将列表和使用方法放在一起的,所以特此总结一下 需要在AndroidManifest.xml中定义相应的权限(以获取internet访问权限为例),如下: X ...

  6. android 列表倒计时,Android ListView列表实现倒计时

    本文实例为大家分享了Android ListView列表实现倒计时的具体代码,供大家参考,具体内容如下 效果图: 1. Activity package com.s296267833.ybs.acti ...

  7. Android聊天列表Demo(QQ,微信,等通讯工具的聊天列表)

     Android聊天列表Demo(QQ,微信,等通讯工具的聊天列表)                                                                  ...

  8. Android 城市列表选择

    最近开发一个城市选择的功能,找了这个文章 Android 城市列表选择 结果发现它使用的拼音转换库pinyin4j有一个很严重的问题,竟然长沙chang sha识别为zhang sha,结果长沙北分在 ...

  9. Android权限列表permission说明 (一)

    原文地址为: Android权限列表permission说明 (一) 网络上不乏android权限列表,但是很少有将列表和使用方法放在一起的,所以特此总结一下 需要在AndroidManifest.x ...

最新文章

  1. Redis 分布式锁使用不当,酿成一个重大事故,超卖了100瓶飞天茅台!!!
  2. 安装和配置本地maven(三)
  3. VC中栈溢出/Stack overflow怎么办?
  4. 利用抽象工厂创建DAO、利用依赖注入去除客户端对工厂的直接依赖、将有关Article的各种Servlet封装到一个Servlet中(通过BaseServlet进行
  5. Andorid ListView使用技巧
  6. teraterm 执行sql命令_tera term的ttl脚本使用方法 | 学步园
  7. 1.有意义的命名(代码的整洁之道)
  8. LeetCode 1871. 跳跃游戏 VII(贪心)
  9. root 链接ftp
  10. Parcel(打包)
  11. 测试 | 测试:你会这些命令吗?
  12. JSP自定义标签rtexprvalue属性 1
  13. 基于python的性能测试工具_基于 Python 的性能测试工具 locust 与 LR 的简单对比[转发]...
  14. 发的楷体怎么写_公布婚期朋友圈怎么发 发结婚通知朋友圈注意哪些
  15. java 多线程 举例,Java多线程简单举例
  16. python 生成 exe
  17. Tomcat中文乱码问题
  18. word使文字垂直居中
  19. 什么可以代替pencil?pencil的平替推荐
  20. 关于excel 打开时提示 文件正在使用 正处于锁定状态 正在编辑 的不治本但简单可行的解决办法

热门文章

  1. chrome 本地文件 翻译工具
  2. pytorch计算FLOPs
  3. 如何在photoshop里画虚线
  4. Github 上 lux 下载神器的安装及使用教程
  5. 如何像「西瓜足迹」一样,将用户导流到公众号上变现?
  6. php zen kaku代表什么,Convert kana one from another (zen-kaku, han-kaku and more) - PHP 7 中文文档...
  7. 一步步看α-β剪枝算法
  8. mysql查询结果某个字段设置为固定值_MySQL使用select查询时,在查询结果中增加一个字段并指定固定值...
  9. 云服务器和虚拟主机有哪些区别
  10. win10睡眠只是关掉显示器的问题