需求描述

越来越多的社交软件通过圆形外框来展现用户头像,因此我们需要将方形源文件以圆形来展示。

实现 src 圆形化显示

完整代码

public class CircleImageView extends ImageView {        private static final String TAG = "CircleImageView";    private Shader mShader;    private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);    public CircleImageView(Context context) {        super(context);    }    @Override    protected void onDraw(Canvas canvas) {        Bitmap rawBitmap = getBitmap(getDrawable());        if (rawBitmap != null) {            int viewWidth = getWidth();            int viewHeight = getHeight();            int viewMinSize = Math.min(viewWidth, viewHeight);            if (mShader == null) {                mShader = new BitmapShader(rawBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);            }            mPaint.setShader(mShader);            float radius = viewMinSize / 2.0f;            canvas.drawCircle(radius, radius, radius, mPaint);        } else {            super.onDraw(canvas);        }    }    private Bitmap getBitmap(Drawable drawable) {        if (drawable instanceof BitmapDrawable) {            return ((BitmapDrawable) drawable).getBitmap();        } else if (drawable instanceof ColorDrawable) {            Rect rect = drawable.getBounds();            int width = rect.width();            int height = rect.height();            int color = ((ColorDrawable) drawable).getColor();            Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);            Canvas canvas = new Canvas(bitmap);            canvas.drawARGB(Color.alpha(color), Color.red(color), Color.green(color),                    Color.blue(color));            return bitmap;        } else {            return null;        }    }}

onDraw() 方法部分注释

    protected void onDraw(Canvas canvas) {        // 通过 getBitMap 方法获取到原始 Bitmap        Bitmap rawBitmap = getBitmap(getDrawable());        // Drawable 是 Bitmap 或 Color        if (rawBitmap != null) {            int viewWidth = getWidth();            int viewHeight = getHeight();            // 由于是圆形,所以需要两者中的 Min。            int viewMinSize = Math.min(viewWidth, viewHeight);            // 判断 Shader 是否已经初始化过,避免绘制过程卡顿。            if (mShader == null) {                // 把原始 Bitmap 给 Shader,模式为拉伸。                mShader = new BitmapShader(rawBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);            }            mPaint.setShader(mShader);            // 得到圆形半径            float radius = viewMinSize / 2.0f;            // 确定绘制 Circle 的中心点、半径和 Paint            canvas.drawCircle(radius, radius, radius, mPaint);        } else {            super.onDraw(canvas);        }    }

getBitmap() 方法部分注释

    private Bitmap getBitmap(Drawable drawable) {        // 如果是 Bitmap 类的 Drawable        if (drawable instanceof BitmapDrawable) {            return ((BitmapDrawable) drawable).getBitmap();        } else if (drawable instanceof ColorDrawable) {            Rect rect = drawable.getBounds();            int width = rect.width();            int height = rect.height();            int color = ((ColorDrawable) drawable).getColor();            // 创建 ARGB_8888 格式的 Bitmap            Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);            Canvas canvas = new Canvas(bitmap);            // 绘制目标颜色,从而把颜色转换为 Bitmap            canvas.drawARGB(Color.alpha(color), Color.red(color), Color.green(color),                    Color.blue(color));            return bitmap;        } else {            return null;        }    }

存在的问题

  1. 对图片资源不会自动缩放,如果是用户自行上传的图片则可能造成资源浪费或者 OOM,但本次需求是系统自带的图标圆形化,所以不需要实现。如果需要实现则可以用 Matrix 实现,可以见文末参考处;

  2. 如果需要加上背景,那么 Background 依然是方形的,而不是圆形。


references:
http://www.cnblogs.com/goagen...
http://www.jianshu.com/p/ed5d...

更多相关文章

  1. android自由改变Dialog窗口位置的方法
  2. Android(安卓)JUnit单元测试基础实例
  3. android中保存Bitmap图片到指定文件夹中的方法
  4. 面试篇--android下网络通讯机制(三种网络通讯方式)
  5. Android(安卓)N NotificationManagerService源码分析
  6. SystemClock.sleep和Thread.sleep源码分析
  7. Android使用Jsoup解析Html表格的方法
  8. Android(安卓)Studio Gradle 重命名输出App或者Library的文件名
  9. Android(安卓)intent传递hashMap对象,遍历hashMap,改变menu状态

随机推荐

  1. 【DB宝31】Oracle DG环境中主库使用rman
  2. JavaScript: 购物车全选自动计算金额和取
  3. 【DB笔试面试845】在Oracle中,sqlnet.ora
  4. 【DB笔试面试66】在Oracle中,关于锁,下列描
  5. 【DB笔试面试571】在Oracle中,如何提高DML
  6. 【DB笔试面试249】在Oracle中,生成备库控
  7. 容器 - container基本介绍和命令示范(5)
  8. 【DB笔试面试573】在Oracle中,常用Hint有
  9. 【DB笔试面试356】在Oracle数据库中,丢失
  10. 【DB笔试面试846】在Oracle中,TWO_TASK环