前言
在软件开发过程中自定义View几乎必不可少,今天写下这篇博客记录自己学习自定义View的第一篇---利用BitmapShader做出圆形图片的效果
先上效果图
思路
整个代码主要使用了三个工具:Paint(画笔-用来绘图),BitmapShader(着色器-拉伸图片,画笔的助手),Martix(矩阵-用来缩放图片,着色器的小助手)
整体思路为:
1.重写onMeasure方法获取View宽高的最小值,并将最小值设置为该View的宽与高
2.获取图片资源,并用着色器拉伸放缩图片
3.将着色器配置给画笔,并在画布上将圆形图案画出来
代码实现
首先新建一个CircleImageView.java的类,让其继承androidx.appcompat.widget.AppCompatImageView
实现三个构造器方法,我们主要用到含两个参数的构造方法。
1.定义初始变量
private Paint mPaint; //创建画笔 private int mRadius; //图片的半径大小 private Matrix mMartix; //缩放图片的矩阵 private Bitmap mBitmap; //Bitmap图片资源 private BitmapShader mBitmapShader; //Bitmap着色器,对bitmap进行拉伸
2.重写onMeasure()函数,获取并设置View的宽高
先通过获取图片的最短宽高让图片的宽度与高度保持一致,除以2后即为半径大小
//通过获取图片的最短宽高让图片的宽高保持一致,除以2后即为半径大小 mRadius = Math.min(getMeasuredWidth(), getMeasuredHeight()) / 2;
然后再重写设置视图的宽高
//重新设置视图的宽高 setMeasuredDimension(mRadius * 2, mRadius * 2);
onMeasure()部分的完整代码为:
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); mRadius = Math.min(getMeasuredWidth(), getMeasuredHeight()) / 2; setMeasuredDimension(mRadius * 2, mRadius * 2); }
3.进行初始化操作
在第二个构造器中添加init()函数
public CircleImageView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); init(); }
新建init()函数,在其中进行初始化操作
第一步先判断是否有图片资源存在,如果没有话就不继续执行后面的方法了
if (getDrawable() == null){ return; }
接下来我们先对画笔,矩阵进行初始化设置,并将Drawable转化为Bitmap
//实例化画笔 mPaint = new Paint(); //实例化矩阵 mMartix = new Matrix(); //获取图片资源,并将drawable图片转化为bitmap图片,便于我们后续的画图 mBitmap = drawableToBitmap(getDrawable());
这里需要用到private void drawableToBitmap(Drawable drawable);函数,将Drawable转化为Bitmap,因为Bitmap一般用来做空白画布画图
在转换函数中我们先判断传进来的drawable是否为BitmapDrawable的实例,如果该drawable为BitmapDrawable的实例,就可以直接进行强制转换
if (drawable instanceof BitmapDrawable){ BitmapDrawable bd = (BitmapDrawable) drawable; return bd.getBitmap(); }
如果不是的话,就可以通过对应的Bitmap画布把drawable内容画到画布中
//取得drawable的宽和高 int width = drawable.getIntrinsicWidth(); int height = drawable.getIntrinsicHeight(); //建立对应的Bitmap Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); //建立对应bitmap的画布 Canvas canvas = new Canvas(bitmap); //把drawable内容画到画布中去 drawable.setBounds(0, 0, width, height); drawable.draw(canvas); return bitmap;
完整转换代码如下:
private Bitmap drawableToBitmap(Drawable drawable){ if (drawable instanceof BitmapDrawable){ BitmapDrawable bd = (BitmapDrawable) drawable; return bd.getBitmap(); } else { //取得drawable的宽和高 int width = drawable.getIntrinsicWidth(); int height = drawable.getIntrinsicHeight(); //建立对应的Bitmap Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); //建立对应bitmap的画布 Canvas canvas = new Canvas(bitmap); //把drawable内容画到画布中去 drawable.setBounds(0, 0, width, height); drawable.draw(canvas); return bitmap; } }
转换为Bitmap后,我们回到init()函数,继续进行对着色器的初始化
新建Bitmap着色器,传入bitmap对象(避免在onDraw函数中初始化),其中后两个参数为平铺模式
TileMode有三种:
CLAMP 拉伸
REPEAT 重复
MIRROR 镜像
//实例化着色器 mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
至此,初始化设置完成。
4.重写onDraw()函数,进行绘制
在绘制函数中主要设置矩阵mMartix,着色器mBitmapShader和画笔mPaint三者的属性
首先我们要为矩阵计算出偏移值,防止因图片的宽高大于View的宽高而造成拉伸效果,即只在圆圈内显示一部分的图像,而不能显示完全
取bitmap宽高的最小值作为基准,计算缩放比例(必须为浮点数) mRadius*2.0f 是指裁剪后View的宽度,在onMeasure()方法里
//图片的缩放比例 float mScale = (mRadius * 2.0f) / Math.min(mBitmap.getWidth(), mBitmap.getHeight());
然后设置矩阵偏移度
//设置矩阵的偏移度 mMartix.setScale(mScale, mScale);
接着我们让着色器装备上设置好的矩阵,这样就不会出现无法显示完图片的问题啦
//设置着色器的矩阵 mBitmapShader.setLocalMatrix(mMartix);
最后,把我们的着色器装配给画笔
//把着色器配给我们的画笔 mPaint.setShader(mBitmapShader);
然后就是整个绘制流程的最后一步啦!调用drawCircle函数用画布把圆画出来
//调用drawCircle函数用画布把圆画出来 canvas.drawCircle(mRadius, mRadius, mRadius, mPaint);
onDraw()函数整体代码如下
@Override protected void onDraw(Canvas canvas) { //取bitmap宽高的最小值作为基准,计算缩放比例(必须为浮点数) mRadius*2.0f 是指裁剪后View的宽度,在onMeasure()方法里 float mScale = (mRadius * 2.0f) / Math.min(mBitmap.getWidth(), mBitmap.getHeight()); //图片的缩放比例 //接下来使用矩阵防止因view的宽高大于bitmap的宽高而造成拉伸效果 //设置矩阵的偏移度 mMartix.setScale(mScale, mScale); //设置着色器的矩阵 mBitmapShader.setLocalMatrix(mMartix); //把着色器配给我们的画笔 mPaint.setShader(mBitmapShader); //调用drawCircle函数用画布把圆画出来 canvas.drawCircle(mRadius, mRadius, mRadius, mPaint); }
圆形图片的绘制至此结束,然后运行你的app,你会发现有三张圆圆的图片显示在你的屏幕上呀。
接下来有时间会在这篇文章后面继续写圆角图片的绘制。
有问题欢迎大家在评论区讨论呀
原文转载:http://www.shaoqun.com/a/499922.html
picitup:https://www.ikjzd.com/w/446
acca是什么:https://www.ikjzd.com/w/1370
review:https://www.ikjzd.com/w/2735
前言在软件开发过程中自定义View几乎必不可少,今天写下这篇博客记录自己学习自定义View的第一篇---利用BitmapShader做出圆形图片的效果先上效果图思路整个代码主要使用了三个工具:Paint(画笔-用来绘图),BitmapShader(着色器-拉伸图片,画笔的助手),Martix(矩阵-用来缩放图片,着色器的小助手)整体思路为:1.重写onMeasure方法获取View宽高的最小值,并
outfit:outfit
telegram:telegram
枕上是仙乡 江南漫游之客栈江湖传说(图) - :枕上是仙乡 江南漫游之客栈江湖传说(图) -
春江游乐求水山景区游乐场儿童免费吗?深圳求水山公园游乐场儿:春江游乐求水山景区游乐场儿童免费吗?深圳求水山公园游乐场儿
【马来西亚旅游签多少钱】--马来西亚旅游签证价格:【马来西亚旅游签多少钱】--马来西亚旅游签证价格
没有评论:
发表评论