大家应该都看到过iOS7解锁屏幕的滑动模糊渐变效果,好了,现在可以把手纸收起来了,今天黄老师就给大家讲一下如何在Android平台上

实现类似的滑动模糊渐变效果,其实方式远比你想像的简单。

目标效果展示:

第一部分:几个前提

说到模糊效果,我们先要了解几个前提

1、原图,指需要被模糊的一张位图

2、模糊,通常是采用指将一个位图的每个像素RGB值都取周围像素的RGB值的平均值,这样就可以产生模糊效果,一般通过高斯函数来实现,

至于Java中的实现方式黄老师就不给大家细讲了,我也不是搞图形算法的,在这方面了解的不比大家多,百度一下能找到一堆高斯模糊转换的实现。

3、模糊半径,指每个像素点周围模糊的半径,半径越大,模糊程度约高,模糊效果越明显,同时,模糊计算耗费时间越长。

4、模糊处理非常费时,一半在100ms~5000ms内,就黄老师我本人找的网上的算法实测,一般android通过java实现的高斯模糊算法转换一张手机

屏幕分辨率为480x800的位图需要2s左右,所以如果要在滑动的过程中实时不断重新计算模糊效果会非常差,所以如果要实现iOS7那样的滑动动态模糊

渐变效果,用这样的方式是不可行的,实际上iOS也不是这么做的,因为iOS的硬件也没达到能实时计算的程度。

那么究竟应该如何去实现模糊渐变呢,其实非常简单,我们接着讲。

第二部分:动态模糊渐变的合理实现方式

其实,我的方式非常简单,首先你需要明确一个最大的模糊效果的模糊半径值,我们给它取个名字叫maxRadius,然后使用maxRadius和原图传入高斯模糊算法

中计算出最大模糊效果的位图maxBlurBitmap。

然后,在ui组件中,假设我的原图是用一个ImageView显示在界面上的,然后你所需要做的是,再创建一个ImageView置于原图ImageView之上,然后将图片源

设置为maxBlurBitmap,如下图:

接着,我们只需要简单的调整maxBlurBitmap的透明度,即可实现模糊渐变效果了,是否很简单呢?

第三部分,提供一个最简单的Java高斯模糊实现,我网上找来的,方便偷懒不愿自己找的同学

001.

1 /**

002.

2  * 位图处理类

003.

3  * @author HalfmanG2

004.

4  */

005.

5 public class BitmapUtil {

006.

6

007.

7     /**

008.

8      * 创建一个虚化的位图

009.

9      * @param sentBitmap 原位图

010.

10      * @param radius 虚化半径

011.

11      * @return 虚化后的位图

012.

12      */

013.

13     public static Bitmap createBlurBitmap(Bitmap sentBitmap,int radius) {

014.

14         Bitmap bitmap = sentBitmap.copy(sentBitmap.getConfig(),true);

015.

15         if (radius <1) {

016.

16             return (null);

017.

17         }

018.

18         int w = bitmap.getWidth();

019.

19         int h = bitmap.getHeight();

020.

20         int[] pix =new int[w * h];

021.

21         bitmap.getPixels(pix,0, w,0,0, w, h);

022.

22         int wm = w -1;

023.

23         int hm = h -1;

024.

24         int wh = w * h;

025.

25         int div = radius + radius +1;

026.

26         int r[] =new int[wh];

027.

27         int g[] =new int[wh];

028.

28         int b[] =new int[wh];

029.

29         int rsum, gsum, bsum, x, y, i, p, yp, yi, yw;

030.

30         int vmin[] =new int[Math.max(w, h)];

031.

31         int divsum = (div +1) >>1;

032.

32         divsum *= divsum;

033.

33         int dv[] =new int[256 * divsum];

034.

34         for (i =0; i <256 * divsum; i++) {

035.

35             dv[i] = (i / divsum);

036.

36         }

037.

37         yw = yi =0;

038.

38         int[][] stack =new int[div][3];

039.

39         int stackpointer;

040.

40         int stackstart;

041.

41         int[] sir;

042.

42         int rbs;

043.

43         int r1 = radius +1;

044.

44         int routsum, goutsum, boutsum;

045.

45         int rinsum, ginsum, binsum;

046.

46         for (y =0; y < h; y++) {

047.

47             rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum =0;

048.

48             for (i = -radius; i <= radius; i++) {

049.

49                 p = pix[yi + Math.min(wm, Math.max(i,0))];

050.

50                 sir = stack[i + radius];

051.

51                 sir[0] = (p &0xff0000) >>16;

052.

52                 sir[1] = (p &0x00ff00) >>8;

053.

53                 sir[2] = (p &0x0000ff);

054.

54                 rbs = r1 - Math.abs(i);

055.

55                 rsum += sir[0] * rbs;

056.

56                 gsum += sir[1] * rbs;

057.

57                 bsum += sir[2] * rbs;

058.

58                 if (i >0) {

059.

59                     rinsum += sir[0];

060.

60                     ginsum += sir[1];

061.

61                     binsum += sir[2];

062.

62                 }else {

063.

63                     routsum += sir[0];

064.

64                     goutsum += sir[1];

065.

65                     boutsum += sir[2];

066.

66                 }

067.

67             }

068.

68             stackpointer = radius;

069.

69             for (x =0; x < w; x++) {

070.

70                 r[yi] = dv[rsum];

071.

71                 g[yi] = dv[gsum];

072.

72                 b[yi] = dv[bsum];

073.

73                 rsum -= routsum;

074.

74                 gsum -= goutsum;

075.

75                 bsum -= boutsum;

076.

76                 stackstart = stackpointer - radius + div;

077.

77                 sir = stack[stackstart % div];

078.

78                 routsum -= sir[0];

079.

79                 goutsum -= sir[1];

080.

80                 boutsum -= sir[2];

081.

81                 if (y ==0) {

082.

82                     vmin[x] = Math.min(x + radius +1, wm);

083.

83                 }

084.

84                 p = pix[yw + vmin[x]];

085.

85                 sir[0] = (p &0xff0000) >>16;

086.

86                 sir[1] = (p &0x00ff00) >>8;

087.

87                 sir[2] = (p &0x0000ff);

088.

88                 rinsum += sir[0];

089.

89                 ginsum += sir[1];

090.

90                 binsum += sir[2];

091.

91                 rsum += rinsum;

092.

92                 gsum += ginsum;

093.

93                 bsum += binsum;

094.

94                 stackpointer = (stackpointer +1) % div;

095.

95                 sir = stack[(stackpointer) % div];

096.

96                 routsum += sir[0];

097.

97                 goutsum += sir[1];

098.

98                 boutsum += sir[2];

099.

99                 rinsum -= sir[0];

100.

100                 ginsum -= sir[1];

101.

101                 binsum -= sir[2];

102.

102                 yi++;

103.

103             }

104.

104             yw += w;

105.

105         }

106.

106         for (x =0; x < w; x++) {

107.

107             rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum =0;

108.

108             yp = -radius * w;

109.

109             for (i = -radius; i <= radius; i++) {

110.

110                 yi = Math.max(0, yp) + x;

111.

111                 sir = stack[i + radius];

112.

112                 sir[0] = r[yi];

113.

113                 sir[1] = g[yi];

114.

114                 sir[2] = b[yi];

115.

115                 rbs = r1 - Math.abs(i);

116.

116                 rsum += r[yi] * rbs;

117.

117                 gsum += g[yi] * rbs;

118.

118                 bsum += b[yi] * rbs;

119.

119                 if (i >0) {

120.

120                     rinsum += sir[0];

121.

121                     ginsum += sir[1];

122.

122                     binsum += sir[2];

123.

123                 }else {

124.

124                     routsum += sir[0];

125.

125                     goutsum += sir[1];

126.

126                     boutsum += sir[2];

127.

127                 }

128.

128                 if (i < hm) {

129.

129                     yp += w;

130.

130                 }

131.

131             }

132.

132             yi = x;

133.

133             stackpointer = radius;

134.

134             for (y =0; y < h; y++) {

135.

135                 pix[yi] = (0xff000000 & pix[yi] ) | ( dv[rsum] <<16 ) | ( dv[gsum] <<8 ) | dv[bsum];

136.

136                 rsum -= routsum;

137.

137                 gsum -= goutsum;

138.

138                 bsum -= boutsum;

139.

139                 stackstart = stackpointer - radius + div;

140.

140                 sir = stack[stackstart % div];

141.

141                 routsum -= sir[0];

142.

142                 goutsum -= sir[1];

143.

143                 boutsum -= sir[2];

144.

144                 if (x ==0) {

145.

145                     vmin[y] = Math.min(y + r1, hm) * w;

146.

146                 }

147.

147                 p = x + vmin[y];

148.

148                 sir[0] = r[p];

149.

149                 sir[1] = g[p];

150.

150                 sir[2] = b[p];

151.

151                 rinsum += sir[0];

152.

152                 ginsum += sir[1];

153.

153                 binsum += sir[2];

154.

154                 rsum += rinsum;

155.

155                 gsum += ginsum;

156.

156                 bsum += binsum;

157.

157                 stackpointer = (stackpointer +1) % div;

158.

158                 sir = stack[stackpointer];

159.

159                 routsum += sir[0];

160.

160                 goutsum += sir[1];

161.

161                 boutsum += sir[2];

162.

162                 rinsum -= sir[0];

163.

163                 ginsum -= sir[1];

164.

164                 binsum -= sir[2];

165.

165                 yi += w;

166.

166             }

167.

167         }

168.

168         bitmap.setPixels(pix,0, w,0,0, w, h);

169.

169         return (bitmap);

170.

170     }

171.

171 }

android 滑动模糊渐变,Android UI效果实现 滑动模糊渐变效果实现相关推荐

  1. android 圆角按钮渐变,Android实现圆形渐变加载进度条

    最近设计要求要一个圆形进度条渐变的需求: 1.画圆形进度条 2.解决渐变 最终实现效果代码 package com.view; import android.content.Context; impo ...

  2. android toolbar 颜色渐变,android – 如何使渐变形状留在CollapsingToolbarLayout标题后面...

    我一直在玩 Chris Bane's Cheesesquare example application关于折叠工具栏布局,我在折叠工具栏上添加标题背后的渐变时,即使背景很亮,标题仍然可读. 该解决方案 ...

  3. android自定义控件颜色渐变,Android编程实现自定义渐变颜色效果详解

    本文实例讲述了Android编程实现自定义渐变颜色效果.分享给大家供大家参考,具体如下: 你是否已经厌恶了纯色的背景呢?那好,Android提供给程序员自定义渐变颜色的接口,让我们的界面炫起来吧. x ...

  4. Android 安卓酷炫View UI效果大全

    这几天开发的时候,想做一些好看而且酷炫的特效,于是又开始从网上收集各种特效资源.下面给大家一些我喜欢的把,附代码,喜欢的看源代码,然后加到自己项目去把!! 1.很简单却很酷的粒子破碎效果   介绍:  ...

  5. Android 11.0 自定义仿小米全面屏手势导航左右手势滑动返回UI效果

    目录 1.概述 2.自定义仿小米全面屏手势导航返回ui布局的核心代码 3.自定义左右手势返回UI样式的核心代码功能分析 3.1 NavigationBarView手势导航布局左右手势返回的相关代码 3 ...

  6. Android UI效果实现——Activity滑动退出效果

    更新说明: 1.在QQ网友北京-旭的提醒下,在SlideFrame的initilize方法中添加了focusable.focusableInTouch.clickable的状态设置,否则会导致部分情况 ...

  7. android 单行文本滚动,Android UI实现单行文本水平触摸滑动效果

    本文实例为大家分享了单行文本水平触摸滑动效果,通过edittext实现textview单行长文本水平滑动效果. 下一篇再为大家介绍 多行文本折叠展开效果,自定义布局view实现多行文本折叠和展开. 1 ...

  8. Android 12.0 自定义仿小米全面屏手势导航左右手势滑动返回UI效果

    目录 1.概述 2.自定义仿小米全面屏手势导航左右手势滑动返回UI效果的核心类

  9. 50个Android开发人员必备UI效果源码[转载]

    Android 仿微信之主页面实现篇 Android 仿微信之界面导航篇 Android 高仿QQ 好友分组列表 Android 高仿QQ 界面滑动效果 Android 高仿QQ 登陆界面 Andro ...

最新文章

  1. AI当道,媒体会被机器牵着鼻子走?
  2. Leap Motion+第六感或引发人机交互革命
  3. git配置服务器版仓库
  4. Windows下MySql安装【图文】
  5. php调用API支付接口(转自刘68)
  6. linux sli 提高效率,从原理到性能提升 MCP78智能SLI全解析
  7. 第二周web作业1:简单的注册表单
  8. UTF-8 Everywhere
  9. 卡通形象医疗病毒细菌宣传海报模板,psd分层,方便应用!
  10. 二调ARCGIS符号库
  11. easycamera arm linux环境下运行时库文件找不到的解决方案
  12. 如何用一句话激怒设计师
  13. 拆书笔记24|笨笨的圣人
  14. CentOS7中安装屏幕键盘(软键盘)
  15. 一张表看懂英式音标和美式音标的差异
  16. 基于 selenium 模拟登陆 12306 滑块问题 已解决
  17. 《调色师手册:电影和视频调色专业技法(第2版)》——第1章 调色的工作流程 我要为电影院(电影)、广播(电视),还是网络调色?...
  18. 微信二次分享链接,出现config:invalid signature错误的解决方法
  19. 举个栗子!Tableau 技巧(158):如何实现双域的服务器单点登录
  20. 第二届华东架构师大会成功召开

热门文章

  1. 如何安装python3.7.4_银河麒麟安装Python3.7.4以及升级自带OpenSSL
  2. 第八届全国功能基因组学高峰论坛-微生物分会场 完美落幕!
  3. Nature子刊:精胺介导稻瘟病菌侵染水稻叶片的新机制!
  4. CHM综述:建立因果关系,合成菌群在植物菌群研究中的机会
  5. NAR:antiSMASH数据库2—次级代谢物基因簇预测
  6. 微生物组:3分和30分文章差距在哪里?
  7. python使用np.argsort对一维numpy概率值数据排序获取倒序索引、获取的top索引(例如top2、top5、top10)索引二维numpy数组中对应的原始数据:原始数据概率最大的头部数据
  8. 珍惜当下、Relish the Moment
  9. 通过构建DCA(Decision Curve Analysis)模型、获取模型数据并使用python进行绘图
  10. mysql存储过程 delete select insert_mysql常见操作语句,建表,增删改查