源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

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

  • 时间:2021-07-28 03:43 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要: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对象的现象。 [b]总结:[/b]多参考优秀的开源项目,用正确的方法做正确的事情! 更多关于Android相关内容感兴趣的读者可查看本站专题:《[url=http://www.1sucai.cn/Special/214.htm]Android图形与图像处理技巧总结[/url]》、《[url=http://www.1sucai.cn/Special/410.htm]Android开发入门与进阶教程[/url]》、《[url=http://www.1sucai.cn/Special/508.htm]Android调试技巧与常见问题解决方法汇总[/url]》、《[url=http://www.1sucai.cn/Special/381.htm]Android基本组件用法总结[/url]》、《[url=http://www.1sucai.cn/Special/375.htm]Android视图View技巧总结[/url]》、《[url=http://www.1sucai.cn/Special/371.htm]Android布局layout技巧总结[/url]》及《[url=http://www.1sucai.cn/Special/124.htm]Android控件用法总结[/url]》 希望本文所述对大家Android程序设计有所帮助。
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部