首页 > 系统 > Android > 正文

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

2020-02-21 17:25:55
字体:
来源:转载
供稿:网友

在android的开发过程中,经常会出现用户上传的图片以圆形的方式显示的情况,今天这篇文章是武林技术频道小编为大家介绍的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编程实现自定义ImageView圆图功能的方法,我们在实际操作中要灵活运用哦,希望能帮助到大家。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表