项目的新launcher设计带有高斯模糊效果,百度到的方法大多数是对一张固定的图片实现毛玻璃效果。而launcher是fragment+viewpager的结构,无法满足滑动时,对背景动态高斯模糊的效果。于是想到在viewpager的滑动监听onPageScrolled方法中对一块区域进行截图,再对此图片进行高斯模糊效果处理,最后设置成一个view的背景。代码实现方法如下:

  /*** viewpager滑动监听*/@Overridepublic void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {initView();int positionOffsetPixels1 = positionOffsetPixels;int count = positionOffsetPixels - OffsetPixel;System.err.println("onPageScrolled______" + OffsetPixel);if (count > 10) {OffsetPixel = count;new Thread() {@Overridepublic void run() {Message msg = Message.obtain();msg.what = UPDATE_BACKGROUND;try {msg.obj = getBitmap(naviView); } catch (Exception e) {e.printStackTrace();}mHandler.sendMessage(msg);}}.start();}}
  /*** 高斯模糊处理*/private Handler mHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);switch (msg.what) {case UPDATE_BACKGROUND:try {naviView.setBackground(new BitmapDrawable((Bitmap) msg.obj));fmView.setBackground(new BitmapDrawable(getBitmap(fmView)));weChat.setBackground(new BitmapDrawable(getBitmap(weChat)));Bitmap source = BitmapFactory.decodeResource(getResources(), R.id.navi);//对Bitmap进行模糊化处理,第一个参数代表原始Bitmap,第二个参数代表模糊半径//半径越大,处理后的图片就越模糊Bitmap bm = NativeStackBlur.process(source, 80);mImageView.setImageBitmap(bm);} catch (Exception e) {e.printStackTrace();}break;}}};

然而,这样做效果太差,滑动时不仅卡顿,部分区域还白屏,于是只能放弃这一种做法。这时,我看到了一博客介绍了一个第三方库http://www.oddjack.com/?certs=mmin18/RealtimeBlurView,效果也是正是我想要的,写了一个demo试了试,完美。具体做法:
1.在app中的build.gradle中依赖:

compile 'com.github.mmin18:realtimeblurview:1.0.3'

2.添加渲染支持:
android {
compileSdkVersion 26
defaultConfig {

    minSdkVersion 17targetSdkVersion 26versionCode 1versionName "1.0"renderscriptTargetApi 26renderscriptSupportModeEnabled true //开启渲染模式支持  一定要加testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}

3.在布局中,将自定义控件放在最下层,这样的效果只对背景进行高斯模糊效果处理

<com.github.mmin18.widget.RealtimeBlurViewandroid:layout_width="160dp"android:layout_height="match_parent"app:realtimeBlurRadius="20dp"     //这个自定义属性代表虚化程度 50 最高,0 最低app:realtimeOverlayColor="#1000" />  //改变透明度 1-9

也可以不依赖第三方库,自己写一个自定义控件,也是上述第三库的全部源码。代码如下:

public class RealtimeBlurView extends View {private float mDownsampleFactor; // default 4private int mOverlayColor; // default #aaffffffprivate float mBlurRadius; // default 10dp (0 < r <= 25)private boolean mDirty;private Bitmap mBitmapToBlur, mBlurredBitmap;private Canvas mBlurringCanvas;private RenderScript mRenderScript;private ScriptIntrinsicBlur mBlurScript;private Allocation mBlurInput, mBlurOutput;private boolean mIsRendering;private Paint mPaint;private final Rect mRectSrc = new Rect(), mRectDst = new Rect();// mDecorView should be the root view of the activity (even if you are on a different window like a dialog)private View mDecorView;// If the view is on different root view (usually means we are on a PopupWindow),// we need to manually call invalidate() in onPreDraw(), otherwise we will not be able to see the changesprivate boolean mDifferentRoot;private static int RENDERING_COUNT;public RealtimeBlurView(Context context, AttributeSet attrs) {super(context, attrs);TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RealtimeBlurView);mBlurRadius = a.getDimension(R.styleable.RealtimeBlurView_realtimeBlurRadius,TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, context.getResources().getDisplayMetrics()));mDownsampleFactor = a.getFloat(R.styleable.RealtimeBlurView_realtimeDownsampleFactor, 4);mOverlayColor = a.getColor(R.styleable.RealtimeBlurView_realtimeOverlayColor, 0xAAFFFFFF);a.recycle();mPaint = new Paint();}public void setBlurRadius(float radius) {if (mBlurRadius != radius) {mBlurRadius = radius;mDirty = true;invalidate();}}public void setDownsampleFactor(float factor) {if (factor <= 0) {throw new IllegalArgumentException("Downsample factor must be greater than 0.");}if (mDownsampleFactor != factor) {mDownsampleFactor = factor;mDirty = true; // may also change blur radiusreleaseBitmap();invalidate();}}public void setOverlayColor(int color) {if (mOverlayColor != color) {mOverlayColor = color;invalidate();}}private void releaseBitmap() {if (mBlurInput != null) {mBlurInput.destroy();mBlurInput = null;}if (mBlurOutput != null) {mBlurOutput.destroy();mBlurOutput = null;}if (mBitmapToBlur != null) {mBitmapToBlur.recycle();mBitmapToBlur = null;}if (mBlurredBitmap != null) {mBlurredBitmap.recycle();mBlurredBitmap = null;}}private void releaseScript() {if (mRenderScript != null) {mRenderScript.destroy();mRenderScript = null;}if (mBlurScript != null) {mBlurScript.destroy();mBlurScript = null;}}protected void release() {releaseBitmap();releaseScript();}protected boolean prepare() {if (mBlurRadius == 0) {release();return false;}float downsampleFactor = mDownsampleFactor;float radius = mBlurRadius / downsampleFactor;if (radius > 25) {downsampleFactor = downsampleFactor * radius / 25;radius = 25;}if (mDirty || mRenderScript == null) {if (mRenderScript == null) {try {mRenderScript = RenderScript.create(getContext());mBlurScript = ScriptIntrinsicBlur.create(mRenderScript, Element.U8_4(mRenderScript));} catch (android.support.v8.renderscript.RSRuntimeException e) {if (isDebug(getContext())) {if (e.getMessage() != null && e.getMessage().startsWith("Error loading RS jni library: java.lang.UnsatisfiedLinkError:")) {throw new RuntimeException("Error loading RS jni library, Upgrade buildToolsVersion=\"24.0.2\" or higher may solve this issue");} else {throw e;}} else {// In release mode, just ignorereleaseScript();return false;}}}mBlurScript.setRadius(radius);mDirty = false;}final int width = getWidth();final int height = getHeight();int scaledWidth = Math.max(1, (int) (width / downsampleFactor));int scaledHeight = Math.max(1, (int) (height / downsampleFactor));if (mBlurringCanvas == null || mBlurredBitmap == null|| mBlurredBitmap.getWidth() != scaledWidth|| mBlurredBitmap.getHeight() != scaledHeight) {releaseBitmap();boolean r = false;try {mBitmapToBlur = Bitmap.createBitmap(scaledWidth, scaledHeight, Bitmap.Config.ARGB_8888);if (mBitmapToBlur == null) {return false;}mBlurringCanvas = new Canvas(mBitmapToBlur);mBlurInput = Allocation.createFromBitmap(mRenderScript, mBitmapToBlur,Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);mBlurOutput = Allocation.createTyped(mRenderScript, mBlurInput.getType());mBlurredBitmap = Bitmap.createBitmap(scaledWidth, scaledHeight, Bitmap.Config.ARGB_8888);if (mBlurredBitmap == null) {return false;}r = true;} catch (OutOfMemoryError e) {// Bitmap.createBitmap() may cause OOM error// Simply ignore and fallback} finally {if (!r) {releaseBitmap();return false;}}}return true;}protected void blur(Bitmap bitmapToBlur, Bitmap blurredBitmap) {mBlurInput.copyFrom(bitmapToBlur);mBlurScript.setInput(mBlurInput);mBlurScript.forEach(mBlurOutput);mBlurOutput.copyTo(blurredBitmap);}private final ViewTreeObserver.OnPreDrawListener preDrawListener = new ViewTreeObserver.OnPreDrawListener() {@Overridepublic boolean onPreDraw() {final int[] locations = new int[2];Bitmap oldBmp = mBlurredBitmap;View decor = mDecorView;if (decor != null && isShown() && prepare()) {boolean redrawBitmap = mBlurredBitmap != oldBmp;oldBmp = null;decor.getLocationOnScreen(locations);int x = -locations[0];int y = -locations[1];getLocationOnScreen(locations);x += locations[0];y += locations[1];// just erase transparentmBitmapToBlur.eraseColor(mOverlayColor & 0xffffff);int rc = mBlurringCanvas.save();mIsRendering = true;RENDERING_COUNT++;try {mBlurringCanvas.scale(1.f * mBitmapToBlur.getWidth() / getWidth(), 1.f * mBitmapToBlur.getHeight() / getHeight());mBlurringCanvas.translate(-x, -y);if (decor.getBackground() != null) {decor.getBackground().draw(mBlurringCanvas);}decor.draw(mBlurringCanvas);} catch (StopException e) {} finally {mIsRendering = false;RENDERING_COUNT--;mBlurringCanvas.restoreToCount(rc);}blur(mBitmapToBlur, mBlurredBitmap);if (redrawBitmap || mDifferentRoot) {invalidate();}}return true;}};protected View getActivityDecorView() {Context ctx = getContext();for (int i = 0; i < 4 && ctx != null && !(ctx instanceof Activity) && ctx instanceof ContextWrapper; i++) {ctx = ((ContextWrapper) ctx).getBaseContext();}if (ctx instanceof Activity) {return ((Activity) ctx).getWindow().getDecorView();} else {return null;}}@Overrideprotected void onAttachedToWindow() {super.onAttachedToWindow();mDecorView = getActivityDecorView();if (mDecorView != null) {mDecorView.getViewTreeObserver().addOnPreDrawListener(preDrawListener);mDifferentRoot = mDecorView.getRootView() != getRootView();if (mDifferentRoot) {mDecorView.postInvalidate();}} else {mDifferentRoot = false;}}@Overrideprotected void onDetachedFromWindow() {if (mDecorView != null) {mDecorView.getViewTreeObserver().removeOnPreDrawListener(preDrawListener);}release();super.onDetachedFromWindow();}@Overridepublic void draw(Canvas canvas) {if (mIsRendering) {// Quit here, don't draw views above methrow STOP_EXCEPTION;} else if (RENDERING_COUNT > 0) {// Doesn't support blurview overlap on another blurview} else {super.draw(canvas);}}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);drawBlurredBitmap(canvas, mBlurredBitmap, mOverlayColor);}/*** Custom draw the blurred bitmap and color to define your own shape** @param canvas* @param blurredBitmap* @param overlayColor*/protected void drawBlurredBitmap(Canvas canvas, Bitmap blurredBitmap, int overlayColor) {if (blurredBitmap != null) {mRectSrc.right = blurredBitmap.getWidth();mRectSrc.bottom = blurredBitmap.getHeight();mRectDst.right = getWidth();mRectDst.bottom = getHeight();canvas.drawBitmap(blurredBitmap, mRectSrc, mRectDst, null);}mPaint.setColor(overlayColor);canvas.drawRect(mRectDst, mPaint);}private static class StopException extends RuntimeException {}private static StopException STOP_EXCEPTION = new StopException();static {try {RealtimeBlurView.class.getClassLoader().loadClass("android.support.v8.renderscript.RenderScript");} catch (ClassNotFoundException e) {throw new RuntimeException("RenderScript support not enabled. Add \"android { defaultConfig { renderscriptSupportModeEnabled true }}\" in your build.gradle");}}// android:debuggable="true" in AndroidManifest.xml (auto set by build tool)static Boolean DEBUG = null;static boolean isDebug(Context ctx) {if (DEBUG == null && ctx != null) {DEBUG = (ctx.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;}return DEBUG == Boolean.TRUE;}
}

PS:demo上程序运行没问题,把代码移植到项目工程里,运行时报错:so文件引用重复 ,解决了还是不行,后来费了老大劲才发现是编译时,系统库下面没有librsjni.so这个so文件。

关于滑动时对背景动态高斯模糊的自定义控件相关推荐

  1. 仿网易云音乐日推界面(监听AppBarLayout滑动+动态高斯模糊)

    首先来看下日推界面的效果: 网易云音乐日推界面的亮点就是在上拉的时候,banner页面逐渐模糊.字体透明度下降,最后左上角显示出"每日推荐"的字体. 这个界面用户会觉得很清晰.便捷 ...

  2. axure9怎么让页面上下滑动_Axure制作:页面上下滑动时的菜单栏悬浮吸顶效果

    昆仑女神的故事,sem优化,破产管理人 在移动端页面上,用手上下滑时,超过一定向上滑动时,菜单栏能有吸顶效果,如何用axure实现呢? 作者在最近在手机移动端的时候,有一个动画,希望达到效果:用手上下 ...

  3. android ListView包含Checkbox滑动时状态改变

    题外话: 在xamarin android的开发中基本上所有人都会遇到这个小小的坎,的确有点麻烦,当时我也折腾了好一半天,如果你能看到这篇博客,说明你和我当初也是一样的焦灼,如果你想解决掉这个小小的坎 ...

  4. 完美解决vue项目中弹出框滑动时,内部页面也跟着滑动问题

    完美解决vue项目中弹出框滑动时,内部页面也跟着滑动问题 参考文章: (1)完美解决vue项目中弹出框滑动时,内部页面也跟着滑动问题 (2)https://www.cnblogs.com/qhanti ...

  5. 优化tableView性能(针对滑动时出现卡的现象)

    优化tableView性能(针对滑动时出现卡的现象) 在iOS应用中,UITableView应该是使用率最高的视图之一了.iPod.时钟.日历.备忘录.Mail.天气.照片.电话.短信. Safari ...

  6. android点击弹出滑动条,IndicatorSeekBar Android自定义SeekBar,滑动时弹出气泡指示器显示进度...

    overview.png 之前在网上看到了当Slider控件在滑动时会弹出气泡指示器,觉得很有趣,于是就进行拓展,就有了下面介绍的一个安卓控件:IndicatorSeekBar.先附上Indicato ...

  7. PL\SQL 打开时出现动态执行表不可访问,本会话的自动统计被禁止

    PL\SQL 打开时出现"动态执行表不可访问,本会话的自动统计被禁止" 博客分类:  数据库 SQLBlog 转自:http://hi.baidu.com/victorlin23/ ...

  8. [置顶]android ListView包含Checkbox滑动时状态改变

    题外话: 在xamarin android的开发中基本上所有人都会遇到这个小小的坎,的确有点麻烦,当时我也折腾了好一半天,如果你能看到这篇博客,说明你和我当初也是一样的焦灼,如果你想解决掉这个小小的坎 ...

  9. Fresco对Listview等快速滑动时停止加载

    Fresco中在listview之类的快速滑动时停止加载,滑动停止后恢复加载: 1.设置图片请求是否开启 [java] view plaincopy print? // 暂停图片请求 public s ...

最新文章

  1. 互联网时代大数据的核心价值
  2. 依图超车争夺AI创业第一股!冲刺科创板,募资75亿为造芯,去年营收91%投向研发...
  3. 回顾JAVA---1.概述及基本语法
  4. 该错误是如何发生的? Git一分为二进行营救!
  5. 为什么不用小驼峰也能查到数据库数据_为什么不用驼峰命名创建表名和字段?...
  6. 编码发生错误时,要注意文件之间的关联性问题!
  7. ios换肤思想,及工具类
  8. python中的filter函数
  9. 批量获取中国所有行政区域经边界纬度坐标(到县区级别)
  10. 0x80070079信号灯超时_windows server 2012 连接共享报0x80070079 信号灯超时时间已到
  11. axure导出html侧边栏,Axure模板库(5)-侧边栏
  12. 如何为长期旅行做准备
  13. 怎样在 kibana 中查看 es elasticsearch lucene 的版本
  14. TCP/IP 第1章 概 述
  15. 如何删除和添加word的脚注那个横线
  16. HDLBits(4) Procedures合集
  17. 【机器学习】李宏毅 - 01 机器学习导论
  18. 浅谈表面反射——波动光学篇
  19. mybatis-plus巨坑--死锁
  20. Ufs测试硬盘的软件,Ufs格式的硬盘在WINDOWS下的读取程序

热门文章

  1. c 语言 蒙特卡洛程序,蒙特卡洛步骤学习(一)
  2. JavaScript的调试工具
  3. Flask-Assets 使用autoprefixer并压缩css/JS文件提高访问速度
  4. 英伟达Tesla T4 显卡编解码能力测试
  5. bootstrap v3.3.6 版本.table-striped不起作用的问题
  6. KDJ、RSI、MACD
  7. Python爬虫入门教程 99-100 Python爬虫在线服务大全
  8. 简单控件的应用(二)—学生管理系统
  9. 低代码里程碑版—JeecgBoot 3.4.3 版本发布,低代码功能专项升级
  10. Elasticsearch集群监控指标学习