zoukankan      html  css  js  c++  java
  • Android ImageView加载圆形图片且同时绘制圆形图片的外部边缘边线及边框

    

    Android ImageView加载圆形图片且同时绘制圆形图片的外部边缘边线及边框


    在Android早期的开发中,如果涉及到圆形图片的处理,往往需要借助于第三方的实现,见附录文章1,2。Android本身并未从SDK层面支持圆形图。但是在后来最新的Android SDK中,增加了对于圆形、圆角图的支持,引入了RoundedBitmapDrawable,RoundedBitmapDrawable的作用是将一个常规图片修剪成圆形或圆角图。RoundedBitmapDrawable的出现,从此在处理简单圆形、圆角图时候简单多了。
    但是,对于复杂设计效果的实现,仅仅有一个RoundedBitmapDrawable是不够的,比如,有这样一种设计要求:把一个常规图片修剪成圆形,同时在圆形图边缘部分描出一定宽度的圆形边框,在圆形边框外在描绘出一圈边线,边线与边框之间还要求透明,这种需求,可能要重写ImageView来实现了。
    把这个需求分解:
    1,首先把常规图片处理成圆形图简单,直接RoundedBitmapDrawable完成。
    2,圆形图外部边缘的圆形边框,则需要重写ImageView,在onDraw里面画圆,画一定宽度的圆,但是这一步在计算圆半径时候容易出问题,因为使用getWidth或getHeight这样的方法获得长度除以2算半径时候,整数除法在计算时候要取整,导致圆半径有一定偏差,进而导致画圆的半径不是刚好与圆形图的外部边缘紧密咬合在一起。故需要引入一个平衡因子消除误差。
    3,画最外层的圆形边线不用考虑那么复杂,和最内层的圆形边框在半径上拉开一定间距即可。


    处理常规图片为圆角的关键代码:

    ImageView imageView= (ImageView) findViewById(R.id.imageView);
    
            RoundedBitmapDrawable circleDrawable = RoundedBitmapDrawableFactory.create(getResources(), BitmapFactory.decodeResource(getResources(), R.drawable.art));
            circleDrawable.getPaint().setAntiAlias(true);
            circleDrawable.setCircular(true);
    
            imageView.setImageDrawable(circleDrawable);


    重写ImageView描绘内层的圆形边框以及最外层的圆形边线:

    package cn.migu.musicplayer.view;
    
    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.Rect;
    import android.util.AttributeSet;
    import android.widget.ImageView;
    
    /**
     * Created by Phil on 2016/7/15.
     */
    public class ImageViewWithStroke extends ImageView {
    
        //外圈白线和内圈黑线边框之间的间隔。
        private int gap = 25;
    
        //平衡在计算半径时候因为除以2导致半径计算的误差
        private int balance_factor = 2;
    
        public ImageViewWithStroke(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }
    
        public ImageViewWithStroke(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public ImageViewWithStroke(Context context) {
            super(context);
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
    
            drawInnerBlackCircle(canvas, 4);
            drawOutWhiteCircle(canvas, 1);
        }
    
    
        //画最外层的白色边线
        private void drawOutWhiteCircle(Canvas canvas, int strokeWidth) {
            Paint paint = new Paint();
            paint.setColor(Color.WHITE);
            paint.setStrokeWidth(strokeWidth);
            paint.setStyle(Paint.Style.STROKE);
            paint.setAntiAlias(true);
    
            int w = this.getPaddingLeft() + this.getPaddingRight();
            int x = getWidth() - w;
            int r = x / 2;
    
            canvas.drawCircle(getWidth() / 2, getHeight() / 2, r + strokeWidth + gap, paint);
        }
    
        //画最内层的黑色边框
        private void drawInnerBlackCircle(Canvas canvas, int strokeWidth) {
            Paint paint = new Paint();
            paint.setColor(Color.BLACK);
            paint.setStrokeWidth(strokeWidth);
            paint.setStyle(Paint.Style.STROKE);
            paint.setAntiAlias(true);
    
            int w = this.getPaddingLeft() + this.getPaddingRight();
            float x = getWidth() - w;
            float r = x / 2;
    
            //半径减去平衡因子是因为在取整时候四舍五入
            canvas.drawCircle(getWidth() / 2, getHeight() / 2, (r - balance_factor) + strokeWidth, paint);
        }
    }
    



    需要处理和加载的目标图片art.jpg:



    代码运行结果:


    背景的绿色图是在ImageView的background加载一张Android自带的小机器人图。


    附录:
    1,《Android圆形头像图Circle ImageView》链接地址:http://blog.csdn.net/zhangphil/article/details/44960551 
    2,《Android CustomShapeImageView对图片进行各种样式裁剪:圆形、星形、心形、花瓣形等》链接地址:http://blog.csdn.net/zhangphil/article/details/50119921

  • 相关阅读:
    通俗理解乐观锁和悲观锁
    面试系列-HashMap和Hashtable的区别
    单点登录原理与实现
    CodeReview常见代码问题
    漫画:什么是冒泡排序?
    Redis 和 Memcached 的区别
    动态图文了解 8 大排序算法
    分布式系统常见的事务处理机制
    面试系列-String,StringBuffer,StringBuilder三者区别
    面试系列-高并发之synchronized
  • 原文地址:https://www.cnblogs.com/hehehaha/p/6147281.html
Copyright © 2011-2022 走看看