记得去年做项目的时候,有涉及到毛玻璃遮罩层的功能,但是因为项目时间太紧,所以放弃了毛玻璃的效果,索性最近有时间就学习记录一波 ~ 文中细节并没有去处理,只是用最简单的方式,实现了我的需求 ~
半成品 - Demo 效果
注 :个人感觉,更适合整体遮罩层
关于更具体的详情,请查看文末的借鉴文章之处 > <~
1.Java实现,一般都是采用Stack模糊算法 (亲测:频繁invalidate(),模糊效果消失)
2.RenderScript实现 (亲测:频繁invalidate(),模糊效果消失)
3.Native实现 (未尝试)
4.OpenCV或者OpenGL实现(未尝试)
注:只用到了blurkit:blk_fps属性,其他属性一用就报错,崩溃的那种,具体问题没有去排查,因为懒 ~
看别人的博客也存在这样的问题,原话是这样的:在blurkit-android的目前的代码中(包括最新版本),BlurLayout的blk_alpha属性并不能使用。因为在代码中存在类型转换错误。英语好的同学可以去提issue
当然他说的是blk_alpha属性 - - 有机会我在重新尝试
//每过1000/fps的时间重新绘制一次BlurLayout,
blurkit:blk_fps="60"
//透明度
blurkit:blk_alpha="0.5"
//模糊半径
blurkit:blk_blurRadius="15"
//BlurLayout的圆角半径
blurkit:blk_cornerRadius="30dp"
//缩放大小,是先放大再缩小,所以值太大则有可能OOM
blurkit:blk_downscaleFactor="0.12"
//进行BlurKit初始化,在Application中初始化
BlurKit.init(this);
//通过RenderScript进行高斯模糊并返回一个bitmap,iv1可以是一个View,也可以是一个ViewGroup,25是模糊半径
Bitmap bt=BlurKit.getInstance().blur(iv1, 25);
//通过RenderScript进行高斯模糊并返回一个bitmap,传入的是一个bitmap,25是模糊半径
Bitmap bt=BlurKit.getInstance().blur(bitmap, 25);
//通过RenderScript进行高斯模糊并返回一个bitmap,iv1可以是一个View,也可以是一个ViewGroup,25是模糊半径,2代表缩放比例,如果值太大可能会出现OOM
Bitmap bt=BlurKit.getInstance().fastBlur(iv1,25,2)
//在类BlurKit中
public Bitmap blur(Bitmap src, int radius) {
final Allocation input = Allocation.createFromBitmap(rs, src);
final Allocation output = Allocation.createTyped(rs, input.getType());
final ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
script.setRadius(radius);
script.setInput(input);
script.forEach(output);
output.copyTo(src);
return src;
}
注 :
要使用blurkit-android的1.1.1版本(目前最新版本),不要使用1.1.0版本(虽然GitHub上的使用文档还是1.1.0)
因为使用1.1.1版本时minSdkVersion的值可以是17,而使用1.1.0版本时minSdkVersion的值必须是21
implementation 'io.alterac.blurkit:blurkit:1.1.1'
@Override
protected void onStart() {
super.onStart();
blurLayout.startBlur();
blurLayout.lockView();
}
@Override
protected void onStop() {
super.onStop();
blurLayout.pauseBlur();
}
package nkwl.com.glassdemo;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import io.alterac.blurkit.BlurLayout;
public class MainActivity extends AppCompatActivity {
private BlurLayout blurLayout;
private TextView mStart;
private TextView mStop;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mStart = findViewById(R.id.tv_start);
mStop = findViewById(R.id.tv_stop);
blurLayout = findViewById(R.id.blurLayout);
mStart.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "开始模糊", Toast.LENGTH_LONG).show();
blurLayout.setVisibility(View.VISIBLE);
}
});
mStop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "停止模糊", Toast.LENGTH_LONG).show();
blurLayout.setVisibility(View.GONE);
}
});
}
@Override
protected void onStart() {
super.onStart();
blurLayout.startBlur();
blurLayout.lockView();
}
@Override
protected void onStop() {
super.onStop();
blurLayout.pauseBlur();
}
}
半成品 - Demo 效果 (模糊效果有点丑 - -)
注 :个人感觉,更适合单一控件
//for ViewGroup 亲测无效,可能是个人原因
Blurry.with(context)
.radius(10)//模糊半径
.sampling(8)//缩放大小,先缩小再放大
.color(Color.argb(66, 255, 255, 0))//颜色
.async()//是否异步
.animate(500)//显示动画,目前仅支持淡入淡出,默认时间是300毫秒,仅支持传入控件为ViewGroup
.onto(viewGroup);
//for view
Blurry.with(context) 亲测无效,可能是个人原因
.radius(10)//模糊半径
.sampling(8)//缩放大小,先缩小再放大
.color(Color.argb(66, 255, 255, 0))//颜色
.async()//是否异步
.capture(view)//传入View
.into(view);//显示View
//for bitmap 亲测有效
Blurry.with(context)
.radius(10)//模糊半径
.sampling(8)//缩放大小,先缩小再放大
.color(Color.argb(66, 255, 255, 0))//颜色
.async()//是否异步
.from(bitmap)//传入bitmap
.into(view);//显示View
注:只实现了第三种使用方法
implementation 'jp.wasabeef:blurry:3.0.0'
package nkwl.com.glassdemo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;
import jp.wasabeef.blurry.Blurry;
public class MainActivity extends AppCompatActivity {
private ImageView mAlineView;
private Bitmap bitmap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mAlineView = findViewById(R.id.tv_aline_view);
//本地图片转为bitmap进行数据传入
bitmap = BitmapFactory.decodeResource(this.getResources(), R.mipmap.bg);
findViewById(R.id.tv_start).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "开始模糊", Toast.LENGTH_LONG).show();
Blurry.with(MainActivity.this)
.radius(10)//模糊半径
.sampling(8)//缩放大小,先缩小再放大
.color(Color.argb(66, 255, 255, 0))//颜色
.async()//是否异步
.from(bitmap)//传入View
.into(mAlineView);//显示View
}
});
findViewById(R.id.tv_stop).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "停止模糊", Toast.LENGTH_LONG).show();
Blurry.with(MainActivity.this)
.radius(10)//模糊半径
.sampling(8)//缩放大小,先缩小再放大
.color(Color.argb(0, 0, 0, 0))//颜色
.async()//是否异步
.from(bitmap)//传入View
.into(mAlineView);//显示View
}
});
}
}