欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android编程实现自定义ImageView圆图功能的方法

程序员文章站 2023-11-20 19:27:58
本文实例讲述了android编程实现自定义imageview圆图功能的方法。分享给大家供大家参考,具体如下: 首先很感谢开源项目universal image loade...

本文实例讲述了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程序设计有所帮助。