美文网首页Android学习知识Android知识Android开发
一个简单的自定义CircleDrawable,实现圆形头像效果

一个简单的自定义CircleDrawable,实现圆形头像效果

作者: blink_dagger | 来源:发表于2016-11-22 08:50 被阅读485次

    Github上有一个star5000+的CircleImageView,代码设计得十分简洁流畅,其实通过自定义一个Drawable也完全可以实现这个效果。(ps:其实是今天在看源码的时候,在Setting模块看到了一个类似的CircleFramedDrawable~,自己几乎没有修改就能实现圆形图片的效果)。

    因为代码十分简单,所以一些简单分析就直接写在注释里了。这里只说一下实现思路:通过为画笔设置PorterDuff.Mode,来让新建的圆形图层与原Bitmap只显示重合部分。(PorterDuff.Mode:一个强大的图像转换模式,使用它,可以使用图像合成的16条Porter-Duff规则的任意一条来控制Paint如何与已有的Canvas图像进行交互。哈哈,说人话就是用来控制图层与图层之间如何覆盖,覆盖之后取哪部分显示到画布上,有兴趣的可以自行百度,这里只用到了两种模式。)

    下面直接上代码和效果图:

    在构造方法里处理图层关系:
        public CircleFramedDrawable(Bitmap icon, int size) {
            super();
            mSize = size;
    
            mBitmap = Bitmap.createBitmap(mSize, mSize, Bitmap.Config.ARGB_8888);
            final Canvas canvas = new Canvas(mBitmap);
    
            final int width = icon.getWidth();
            final int height = icon.getHeight();
            final int square = Math.min(width, height);
    
            final Rect cropRect = new Rect((width - square) / 2, (height - square) / 2, square, square);
            final RectF circleRect = new RectF(0f, 0f, mSize, mSize);
    
            final Path fillPath = new Path();
            //path.addArc方法用于绘制圆弧,这个圆弧取自RectF矩形的内接椭圆上的一部分,圆弧长度由后两个角度参数决定
            fillPath.addArc(circleRect, 0f, 360f);
            //PorterDuff.Mode.CLEAR:清除画布(所绘制不会提交到画布上)
            canvas.drawColor(0, PorterDuff.Mode.CLEAR);
    
            // opaque circle matte
            mPaint = new Paint();
            mPaint.setAntiAlias(true);
            mPaint.setColor(Color.BLACK);
            mPaint.setStyle(Paint.Style.FILL);
            canvas.drawPath(fillPath, mPaint);
    
            // mask in the icon where the bitmap is opaque(不透明)
            //PorterDuff.Mode.SRC_IN:两者相交的地方绘制源图
            mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
            canvas.drawBitmap(icon, cropRect, circleRect, mPaint);
    
            // prepare paint for frame drawing
            // 别忘记还原画笔~
            mPaint.setXfermode(null);
    
            mScale = 1f;
    
            mSrcRect = new Rect(0, 0, mSize, mSize);
            mDstRect = new RectF(0, 0, mSize, mSize);
        }
    
    
    当然支持图片的缩放啦:
        @Override
        public void draw(Canvas canvas) {
            //缩放处理
            final float inside = mScale * mSize;
            final float pad = (mSize - inside) / 2f;
            //将矩形的坐标设置为缩放后指定的值
            mDstRect.set(pad, pad, mSize - pad, mSize - pad);
            //第一个mSrcRect代表要绘制的bitmap区域,第二个mDstRect代表的是要将bitmap绘制在屏幕的什么地方
            canvas.drawBitmap(mBitmap, mSrcRect, mDstRect, null);
        }
    
    获取drawable时传入我们想要的大小就可以了
        public static CircleFramedDrawable getInstance(Context context, Bitmap icon,float size) {
            Resources res = context.getResources();
            float iconSize = px2dip(context,size);
            CircleFramedDrawable instance = new CircleFramedDrawable(icon, (int) iconSize);
            return instance;
        }
    
    怎么使用?
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
                    R.drawable.workingdog);
            mIcon.setImageDrawable(CircleFramedDrawable.getInstance(this,bitmap,800));
        }
    

    所以可以不用修改项目中的布局文件,直接加一个Drawable类就能在任何时候转换图片至圆形了!

    效果图:
    <a href="http://i1.piimg.com/4851/94e2b6e0c15ac8cd.png" title="点击显示原始图片">

    </a>

    __*

    <a href="http://i1.piimg.com/4851/ff66c8b39b555482.png" title="点击显示原始图片"> </a>

    Demo地址

    相关文章

      网友评论

      • aa5ba408bfcb:应该加入人脸识别,只截取人脸部分

      本文标题:一个简单的自定义CircleDrawable,实现圆形头像效果

      本文链接:https://www.haomeiwen.com/subject/ohpupttx.html