Android编程实现自定义ImageView圆图功能的方法
本文实例讲述了android编程实现自定义imageview圆图功能的方法。分享给大家供大家参考,具体如下:
首先很感谢开源项目universal image loader图片加载框架。之前也看过一段时间框架源码,但是却没有时间进行知识点的总结。
今天项目遇到了需要实现圆头像的编辑显示,universal就已经提供了这个显示roundedbitmapdisplayer这个类实现了圆图功能。看它的代码可以发现是实现的drawable
public static class roundeddrawable extends drawable { protected final float cornerradius; protected final int margin; protected final rectf mrect = new rectf(), mbitmaprect; protected final bitmapshader bitmapshader; protected final paint paint; public roundeddrawable(bitmap bitmap, int cornerradius, int margin) { this.cornerradius = cornerradius; this.margin = margin; bitmapshader = new bitmapshader(bitmap, shader.tilemode.clamp, shader.tilemode.clamp); mbitmaprect = new rectf (margin, margin, bitmap.getwidth() - margin, bitmap.getheight() - margin); paint = new paint(); paint.setantialias(true); paint.setshader(bitmapshader); } @override protected void onboundschange(rect bounds) { super.onboundschange(bounds); mrect.set(margin, margin, bounds.width() - margin, bounds.height() - margin); // resize the original bitmap to fit the new bound matrix shadermatrix = new matrix(); shadermatrix.setrecttorect(mbitmaprect, mrect, matrix.scaletofit.fill); bitmapshader.setlocalmatrix(shadermatrix); } @override public void draw(canvas canvas) { canvas.drawroundrect(mrect, cornerradius, cornerradius, paint); } @override public int getopacity() { return pixelformat.translucent; } @override public void setalpha(int alpha) { paint.setalpha(alpha); } @override public void setcolorfilter(colorfilter cf) { paint.setcolorfilter(cf); } }
其实总结下来,上面圆图实现步骤就是:
1、通过bitmap初始化位图着色器bitmapshader类
2、计算bitmap原始图片的rect
3、计算放置图片需要的rect
4、使用matrix类对两个rect进行压缩,然后复制给bitmapshader着色器里去。最后是画布画图。
(刚开始一直以为shader是阴影的意思,原来有道一下是着色器的意思,这个翻译其实对我理解代码还是很重要的,所以不要想当然,要勤奋点,这个是优秀程序员必备要素。)
最后我要实现的是继承imageview实现圆图
public class uroundedimageview extends imageview { private paint mbitmappaint,mbackgroundpaint; private bitmapshader mbitmapshader; private rectf mbitmaprect , mrect; private int borderwidth; private bitmap mbitmap; private matrix shadermatrix; public uroundedimageview(context context, attributeset attrs, int defstyleattr) { super(context, attrs, defstyleattr); init(); } public uroundedimageview(context context, attributeset attrs) { super(context, attrs); init(); } public uroundedimageview(context context) { super(context); init(); } private void init(){ mbitmappaint = new paint(); mbitmappaint.setantialias(true); mbackgroundpaint = new paint(); mbackgroundpaint.setantialias(true); mbackgroundpaint.setcolor(color.white); borderwidth = 5; mrect = new rectf(); shadermatrix = new matrix(); } @override protected void onlayout(boolean changed, int left, int top, int right, int bottom) { // todo auto-generated method stub super.onlayout(changed, left, top, right, bottom); } @override protected void ondraw(canvas canvas) { mbitmap = ((bitmapdrawable) getdrawable()).getbitmap(); if (getwidth() == 0 || getheight() == 0 || mbitmap == null) { return; } int w = getwidth(); int h = getheight(); int radius = math.min(w, h) / 2; canvas.drawcircle(w / 2, h / 2, radius, mbackgroundpaint); //传入bitmap初始化位图着色器 if (mbitmapshader == null) { mbitmapshader = new bitmapshader(mbitmap, shader.tilemode.clamp, shader.tilemode.clamp); } if (mbitmaprect == null) { mbitmaprect = new rectf(borderwidth, borderwidth, mbitmap.getwidth() - borderwidth, mbitmap.getheight() - borderwidth); } mbitmappaint.setshader(mbitmapshader); mrect.set(borderwidth, borderwidth, w - borderwidth, h - borderwidth); //对bitmap原始图进行缩放 shadermatrix.setrecttorect(mbitmaprect, mrect, matrix.scaletofit.fill); mbitmapshader.setlocalmatrix(shadermatrix); canvas.drawroundrect(mrect, radius, radius, mbitmappaint); } }
刚开始写的不够规范,直接在ondraw方法里面new一些需要的对象,lint提醒我们avoid object allocations during draw/layout operations (preallocate and reuse instead)这个warning。因为ondraw会不断调用,如果一直new对象的话会吃内存。所以为了避免重复new对象,根据自己的需求进行判空操作。具体根据自己需求来优化代码,有时候为了达到需求也没办法做到在ondraw方法里不出现重复new对象的现象。
总结:多参考优秀的开源项目,用正确的方法做正确的事情!
更多关于android相关内容感兴趣的读者可查看本站专题:《android图形与图像处理技巧总结》、《android开发入门与进阶教程》、《android调试技巧与常见问题解决方法汇总》、《android基本组件用法总结》、《android视图view技巧总结》、《android布局layout技巧总结》及《android控件用法总结》
希望本文所述对大家android程序设计有所帮助。
上一篇: 小米手环怎么设置来电提醒震动提示?