Android(安卓)glide-transformations 使用demo 实现Blur等效果
README
本文对Glide - transformations进行简单的使用说明
Glide - transformations是Android平台一款优秀的图片处理工具
Github地址为:https://github.com/wasabeef/glide-transformations
本文所用到的代码地址:https://github.com/nikolajohn/GlideTransformationDemo
添加Glide依赖
首先在你的Android Studio里新建一个Android项目
然后打开这个文件
打开以后,加上这句话
implementation 'jp.wasabeef:glide-transformations:3.3.0'
就像这样
然后,在你的当前包下面,新建一个java 类,叫Utils
这个类的代码可以这样写
package cn.edu.zju.glidetest;import android.content.Context;public class Utils { public static int dip2px(Context context, float dp) { float scale = context.getResources().getDisplayMetrics().density; return (int) (dp * scale + 0.5f); }}
什么意思呢?其实看函数的名字就知道了,相当于一个量纲的转化
具体为什么要有这样一个转化,以及转化的代码为什么要这样写
可以查看这篇文章: https://blog.csdn.net/arui319/article/details/6777133?utm_source=blogxgwz0
添加RecycleView依赖
接下来,还是回到app目录下的gradle文件里
就是这里
添加如下代码
implementation 'com.android.support:recyclerview-v7:28.0.0'
添加完成后,就是这样的
添加RecycleView控件
接下来,打开MainActivity的布局文件(XML文件)
先把不用的删掉
然后添加RecycleView的控件,代码如下
就像这样
这里,RecycleView控件的id,你可以命名为list,也可以命名为recycler_view
因为你的RecycleView控件并不是内置在系统的SDK中,所以用的时候,需要把完整的包的路径都写出来,而不是像LinearLayout那种,前面没有完整的包名
添加item布局文件
接下来,新建一个Layout文件,这个用于存放你的每一个条目的布局,就叫layout_list_item
这个我们就这样写
<?xml version="1.0" encoding="utf-8"?>
做好之后就是这样的
适配器
接下来,你需要为你的RecycleView准备适配器
那么什么是适配器呢,这个我们看了后面的代码,相信你就会有自己的理解了
新建适配器类的方法很简单,和上面说过的是一样的,这个类的名字就叫做MainAdapter
因为你的这个适配器(Adapter)是针对RecycleView的,所以你需要让这个适配器继承自RecycleView.Adapter这个类,写好之后就像上面这样
此外,我们还需要将泛型指定为MainAdapter.ViewHolder,其中的ViewHolder就是我们在MainAdapter中定义的一个内部类
这个类的构造函数就这样写
第一个参数是你的上下文,这个是常规套路,一般都会有这样的一个context参数
第二个参数是一个List,List中的每一个数据的类型都是Type(这个我们后面再定义,你可以先理解成这就是一个我们自己定义的数据类型),这个数组的名字就叫做dataSet
刚刚我们提到了,需要在这里加一个内部类,如图所示
首先ViewHolder肯定是需要继承自RecyclerView.ViewHolder的
ViewHolder内部的代码其实很简单,写法也是很固定的
首先定义一下,你在每个item布局中用到的东西,比如我们之前用到的是一个ImageView和一个TextView,因此这里就这样定义即可
他的构造函数也很简单,就是把那些layout里的控件找一下就好,这些代码都是常规套路
然后你在你的MainAdpter中定义私有的数据类型,这个也是常规套路了
接下来看一下onCreateViewHolder函数
这个函数的写法还是比较固定的,但是有一点需要注意的是,如果你用上面的这种写法,你必须在MainAdapter里定义私有成员变量context,然后在MainAdapter的构造函数里面赋值一下,就像这样
如果你上面这两句话没有写,那么你的onCreateViewHolder函数应该这样写
@Override public MainAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_list_item, parent, false); return new ViewHolder(v); }
你不这样写,IDE是会报错的
onBindViewHolder
接下来是一个非常重要的函数onBindViewHolder
在做这个函数之前,我们先把一些图片资源加载进来,加载的方式很简单,只要把图片放到你的mipmap文件夹里就好(图片的资源我会放在附件里)
接下来分析这个onBindViewHolder函数,先看代码
@Override public void onBindViewHolder(MainAdapter.ViewHolder holder, int position) { switch (dataSet.get(position)) { case Mask: { int width = Utils.dip2px(context, 266.66f); int height = Utils.dip2px(context, 252.66f); Glide.with(context) .load(R.mipmap.check) .apply(overrideOf(width, height)) .apply(bitmapTransform(new MultiTransformation<>(new CenterCrop(), new MaskTransformation(R.mipmap.mask_starfish)))) .into(holder.image); break; } case NinePatchMask: { int width = Utils.dip2px(context, 300.0f); int height = Utils.dip2px(context, 200.0f); Glide.with(context) .load(R.mipmap.check) .apply(overrideOf(width, height)) .apply(bitmapTransform(new MultiTransformation<>(new CenterCrop(), new MaskTransformation(R.mipmap.mask_chat_right)))) .into(holder.image); break; } case CropTop: Glide.with(context) .load(R.mipmap.demo) .apply(bitmapTransform( new CropTransformation(Utils.dip2px(context, 300), Utils.dip2px(context, 100), CropType.TOP))) .into(holder.image); break; case CropCenter: Glide.with(context) .load(R.mipmap.demo) .apply(bitmapTransform( new CropTransformation(Utils.dip2px(context, 300), Utils.dip2px(context, 100), CropType.CENTER))) .into(holder.image); break; case CropBottom: Glide.with(context) .load(R.mipmap.demo) .apply(bitmapTransform( new CropTransformation(Utils.dip2px(context, 300), Utils.dip2px(context, 100), CropType.BOTTOM))) .into(holder.image); break; case CropSquare: Glide.with(context) .load(R.mipmap.demo) .apply(bitmapTransform(new CropSquareTransformation())) .into(holder.image); break; case CropCircle: Glide.with(context) .load(R.mipmap.demo) .apply(bitmapTransform(new CropCircleTransformation())) .into(holder.image); break; case ColorFilter: Glide.with(context) .load(R.mipmap.demo) .apply(bitmapTransform(new ColorFilterTransformation(Color.argb(80, 255, 0, 0)))) .into(holder.image); break; case Grayscale: Glide.with(context) .load(R.mipmap.demo) .apply(bitmapTransform(new GrayscaleTransformation())) .into(holder.image); break; case RoundedCorners: Glide.with(context) .load(R.mipmap.demo) .apply(bitmapTransform(new RoundedCornersTransformation(45, 0, RoundedCornersTransformation.CornerType.BOTTOM))) .into(holder.image); break; case Blur: Glide.with(context) .load(R.mipmap.check) .apply(bitmapTransform(new BlurTransformation(250))) .into(holder.image); break; case SupportRSBlur: Glide.with(context) .load(R.mipmap.check) .apply(bitmapTransform(new SupportRSBlurTransformation(25, 10))) .into(holder.image); break; case Toon: Glide.with(context) .load(R.mipmap.demo) .apply(bitmapTransform(new ToonFilterTransformation())) .into(holder.image); break; case Sepia: Glide.with(context) .load(R.mipmap.check) .apply(bitmapTransform(new SepiaFilterTransformation())) .into(holder.image); break; case Contrast: Glide.with(context) .load(R.mipmap.check) .apply(bitmapTransform(new ContrastFilterTransformation(2.0f))) .into(holder.image); break; case Invert: Glide.with(context) .load(R.mipmap.check) .apply(bitmapTransform(new InvertFilterTransformation())) .into(holder.image); break; case Pixel: Glide.with(context) .load(R.mipmap.check) .apply(bitmapTransform(new PixelationFilterTransformation(20))) .into(holder.image); break; case Sketch: Glide.with(context) .load(R.mipmap.check) .apply(bitmapTransform(new SketchFilterTransformation())) .into(holder.image); break; case Swirl: Glide.with(context) .load(R.mipmap.check) .apply(bitmapTransform( new SwirlFilterTransformation(0.5f, 1.0f, new PointF(0.5f, 0.5f))).dontAnimate()) .into(holder.image); break; case Brightness: Glide.with(context) .load(R.mipmap.check) .apply(bitmapTransform(new BrightnessFilterTransformation(0.5f)).dontAnimate()) .into(holder.image); break; case Kuawahara: Glide.with(context) .load(R.mipmap.check) .apply(bitmapTransform(new KuwaharaFilterTransformation(25)).dontAnimate()) .into(holder.image); break; case Vignette: Glide.with(context) .load(R.mipmap.check) .apply(bitmapTransform(new VignetteFilterTransformation(new PointF(0.5f, 0.5f), new float[] { 0.0f, 0.0f, 0.0f }, 0f, 0.75f)).dontAnimate()) .into(holder.image); break; } holder.title.setText(dataSet.get(position).name()); }
要分析这个函数,其实很简单
首先看开头
可以看到,这个函数的两个参数分别是ViewHolder的对象和position值
不难猜到,这个函数的作用就是把一个ViewHolder和一个position一一对应起来
那么我们想一下,如果要我们自己写,那么应该怎么写呢
当然是首先拿到position,然后把这个position和对应的viewholder联系起来即可,实际上我们也是这么做的
MASK
对位掩模操作(MASK),你的底层图片(简称底片)大小肯定是确定的,这个我们是不能进行更改的(确切的说,应该是不会去更改,想改还是可以得),因为你的底片大小定义在这里
显然,你的底片大小是:宽250dp 高250dp
那么你的掩模板大小的宽和高都应该接近于250dp,这样掩模的效果是最好的
比如说,我们把掩模板宽设为266dp,高设为252dp
这样做是什么意思呢?就是说,你的掩模板里的东西是多少像素
如果说你按照上面的设置,显示出来的效果是这样的:
如果你把数字改小一些,比如宽慰2dp,高为2dp,那么效果就是这样的:
想明白了这个,接下来就很简单了
Blur
Blur的操作,同样很简单
大部分的参数含义都是和上面一样的,因为少了掩模板的操作,因此Blur的操作其实更加简单
这里需要注意一下的是,radius参数的大小可以决定你的模糊程度,这个数值越大,就越模糊
更多相关文章
- 没有一行代码,「2020 新冠肺炎记忆」这个项目却登上了 GitHub 中
- listView单选实现(一)
- SeekBar的使用
- Android(安卓)通过包名打开App的代码
- Android(安卓)libav移植
- Android(安卓)publickey获取
- android检查手机和无线是否连接的方法
- Android(安卓)GridView宫格视图(一) 运用--BaseAdapter
- Android(安卓)在工作线程(非主线程)更改UI组件