android多任务列表高斯模糊
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多任务列表高斯模糊相关推荐
- android 多任务按钮,XDA大神推出Android多任务切换神器
Android设备都会有专用的按钮来查看和切换多任务列表,例如通过长按Home键来实现.现在切换多任务有了更炫的方式.<Switchr>是一款Android上的多任务切换软件,使用了它之后 ...
- android倒计时功能,Android 实现列表倒计时功能
Android 实现列表倒计时功能 发布时间:2020-08-21 21:47:11 来源:脚本之家 阅读:147 作者:Choi晨 单个计时器,然后遍历数据 刷新条目: 两种实现方式:1.Handl ...
- android优美列表页面,android listview 列表 点击列表进入详细页面
[实例简介] android listview 列表 点击列表进入详细页面 [实例截图] [核心代码] ListviewSingleChoice └── ListviewSingleChoice ├─ ...
- android开发列表界面
android开发列表界面,上边是一个显示题目,下边显示的是图标,中间显示的是列表. 看一下效果吧 当鼠标点击上之后出现背景图,下面看一下如何做出这样的效果吧. 1.创建android工程 修改mai ...
- (转)Android权限列表permission说明 (一)
网络上不乏android权限列表,但是很少有将列表和使用方法放在一起的,所以特此总结一下 需要在AndroidManifest.xml中定义相应的权限(以获取internet访问权限为例),如下: X ...
- android 列表倒计时,Android ListView列表实现倒计时
本文实例为大家分享了Android ListView列表实现倒计时的具体代码,供大家参考,具体内容如下 效果图: 1. Activity package com.s296267833.ybs.acti ...
- Android聊天列表Demo(QQ,微信,等通讯工具的聊天列表)
Android聊天列表Demo(QQ,微信,等通讯工具的聊天列表) ...
- Android 城市列表选择
最近开发一个城市选择的功能,找了这个文章 Android 城市列表选择 结果发现它使用的拼音转换库pinyin4j有一个很严重的问题,竟然长沙chang sha识别为zhang sha,结果长沙北分在 ...
- Android权限列表permission说明 (一)
原文地址为: Android权限列表permission说明 (一) 网络上不乏android权限列表,但是很少有将列表和使用方法放在一起的,所以特此总结一下 需要在AndroidManifest.x ...
最新文章
- Redis 分布式锁使用不当,酿成一个重大事故,超卖了100瓶飞天茅台!!!
- 安装和配置本地maven(三)
- VC中栈溢出/Stack overflow怎么办?
- 利用抽象工厂创建DAO、利用依赖注入去除客户端对工厂的直接依赖、将有关Article的各种Servlet封装到一个Servlet中(通过BaseServlet进行
- Andorid ListView使用技巧
- teraterm 执行sql命令_tera term的ttl脚本使用方法 | 学步园
- 1.有意义的命名(代码的整洁之道)
- LeetCode 1871. 跳跃游戏 VII(贪心)
- root 链接ftp
- Parcel(打包)
- 测试 | 测试:你会这些命令吗?
- JSP自定义标签rtexprvalue属性 1
- 基于python的性能测试工具_基于 Python 的性能测试工具 locust 与 LR 的简单对比[转发]...
- 发的楷体怎么写_公布婚期朋友圈怎么发 发结婚通知朋友圈注意哪些
- java 多线程 举例,Java多线程简单举例
- python 生成 exe
- Tomcat中文乱码问题
- word使文字垂直居中
- 什么可以代替pencil?pencil的平替推荐
- 关于excel 打开时提示 文件正在使用 正处于锁定状态 正在编辑 的不治本但简单可行的解决办法
热门文章
- chrome 本地文件 翻译工具
- pytorch计算FLOPs
- 如何在photoshop里画虚线
- Github 上 lux 下载神器的安装及使用教程
- 如何像「西瓜足迹」一样,将用户导流到公众号上变现?
- php zen kaku代表什么,Convert kana one from another (zen-kaku, han-kaku and more) - PHP 7 中文文档...
- 一步步看α-β剪枝算法
- mysql查询结果某个字段设置为固定值_MySQL使用select查询时,在查询结果中增加一个字段并指定固定值...
- 云服务器和虚拟主机有哪些区别
- win10睡眠只是关掉显示器的问题