关于Android圆形图片的一种优化方案(可以显示网络图片) 关于Android圆形图片的一种优化方案(可以显示网络图片)

关于Android圆形图片的一种优化方案(可以显示网络图片)

在Android App中,我们经常看到圆形头像图片,然后网上也有很多开源的控件。刚好这个项目用到了,也去找了一些开源的,发现并不完美,所以只好自己优化了,废话不多说,先上效果图:

下面是源码:本人能理解的地方都加上注释了,大牛勿喷。

[java] view plain copy
  1. package com.xyt.ygcf.widget;  
  2.   
  3. import android.content.Context;  
  4. import android.content.res.TypedArray;  
  5. import android.graphics.Bitmap;  
  6. import android.graphics.Canvas;  
  7. import android.graphics.Color;  
  8. import android.graphics.Paint;  
  9. import android.graphics.PorterDuff;  
  10. import android.graphics.PorterDuffXfermode;  
  11. import android.graphics.RectF;  
  12. import android.graphics.Xfermode;  
  13. import android.graphics.drawable.Drawable;  
  14. import android.graphics.drawable.NinePatchDrawable;  
  15. import android.util.AttributeSet;  
  16. import android.widget.ImageView;  
  17.   
  18. import com.xyt.yangguangchufang.R;  
  19.   
  20. public class CircleImageView extends ImageView {  
  21.   
  22.     private static final Xfermode MASK_XFERMODE;  
  23.     private Bitmap mask;  
  24.     private Paint paint;  
  25.     private int mBorderWidth = 10;  
  26.     private int mBorderColor = Color.parseColor("#f2f2f2");  
  27.   
  28.     static {  
  29.         PorterDuff.Mode localMode = PorterDuff.Mode.DST_IN;  
  30.         MASK_XFERMODE = new PorterDuffXfermode(localMode);  
  31.     }  
  32.   
  33.     public CircleImageView(Context paramContext) {  
  34.         super(paramContext);  
  35.     }  
  36.   
  37.     public CircleImageView(Context paramContext, AttributeSet paramAttributeSet) {  
  38.         this(paramContext, paramAttributeSet, 0);  
  39.     }  
  40.   
  41.     public CircleImageView(Context paramContext, AttributeSet paramAttributeSet, int paramInt) {  
  42.         super(paramContext, paramAttributeSet, paramInt);  
  43.         TypedArray a = paramContext.obtainStyledAttributes(paramAttributeSet, R.styleable.CircularImage);  
  44.         mBorderColor = a.getColor(R.styleable.CircularImage_border_color, mBorderColor);  
  45.         final int defalut = (int) (2 * paramContext.getResources().getDisplayMetrics().density + 0.5f);  
  46.         mBorderWidth = a.getDimensionPixelOffset(R.styleable.CircularImage_border_width, defalut);  
  47.         a.recycle();  
  48.     }  
  49.   
  50.     private boolean useDefaultStyle = false;  
  51.   
  52.     public void setUseDefaultStyle(boolean useDefaultStyle) {  
  53.         this.useDefaultStyle = useDefaultStyle;  
  54.     }  
  55.   
  56.     @Override  
  57.     protected void onDraw(Canvas paramCanvas) {  
  58.         if (useDefaultStyle) {  
  59.             super.onDraw(paramCanvas);  
  60.             return;  
  61.         }  
  62.         final Drawable localDrawable = getDrawable();  
  63.         if (localDrawable == null)  
  64.             return;  
  65.         if (localDrawable instanceof NinePatchDrawable) {  
  66.             return;  
  67.         }  
  68.         if (this.paint == null) {  
  69.             final Paint localPaint = new Paint();  
  70.             localPaint.setFilterBitmap(false);  
  71.             localPaint.setAntiAlias(true);  
  72.             localPaint.setXfermode(MASK_XFERMODE);  
  73.             this.paint = localPaint;  
  74.         }  
  75.         final int width = getWidth();  
  76.         final int height = getHeight();  
  77.         /** 保存layer */  
  78.         int layer = paramCanvas.saveLayer(0.0F, 0.0F, width, height, null31);  
  79.         /** 设置drawable的大小 */  
  80.         localDrawable.setBounds(00, width, height);  
  81.         /** 将drawable绑定到bitmap(this.mask)上面(drawable只能通过bitmap显示出来) */  
  82.         localDrawable.draw(paramCanvas);  
  83.         if ((this.mask == null) || (this.mask.isRecycled())) {  
  84.             this.mask = createOvalBitmap(width, height);  
  85.         }  
  86.         /** 将bitmap画到canvas上面 */  
  87.         paramCanvas.drawBitmap(this.mask, 0.0F, 0.0F, this.paint);  
  88.         /** 将画布复制到layer上 */  
  89.         paramCanvas.restoreToCount(layer);  
  90.         drawBorder(paramCanvas, width, height);  
  91.     }  
  92.   
  93.     /** 
  94.      * 绘制最外面的边框 
  95.      *  
  96.      * @param canvas 
  97.      * @param width 
  98.      * @param height 
  99.      */  
  100.     private void drawBorder(Canvas canvas, final int width, final int height) {  
  101.         if (mBorderWidth == 0) {  
  102.             return;  
  103.         }  
  104.         final Paint mBorderPaint = new Paint();  
  105.         mBorderPaint.setStyle(Paint.Style.STROKE);  
  106.         mBorderPaint.setAntiAlias(true);  
  107.         mBorderPaint.setColor(mBorderColor);  
  108.         mBorderPaint.setStrokeWidth(mBorderWidth);  
  109.         /** 
  110.          * 坐标x:view宽度的一般 坐标y:view高度的一般 半径r:因为是view的宽度-border的一半 
  111.          */  
  112.         canvas.drawCircle(width >> 1, height >> 1, (width - mBorderWidth) >> 1, mBorderPaint);  
  113.         canvas = null;  
  114.     }  
  115.   
  116.     /** 
  117.      * 获取一个bitmap,目的是用来承载drawable; 
  118.      * <p> 
  119.      * 将这个bitmap放在canvas上面承载,并在其上面画一个椭圆(其实也是一个圆,因为width=height)来固定显示区域 
  120.      *  
  121.      * @param width 
  122.      * @param height 
  123.      * @return 
  124.      */  
  125.     public Bitmap createOvalBitmap(final int width, final int height) {  
  126.         Bitmap.Config localConfig = Bitmap.Config.ARGB_8888;  
  127.         Bitmap localBitmap = Bitmap.createBitmap(width, height, localConfig);  
  128.         Canvas localCanvas = new Canvas(localBitmap);  
  129.         Paint localPaint = new Paint();  
  130.         final int padding = mBorderWidth - 3;  
  131.         /** 
  132.          * 设置椭圆的大小(因为椭圆的最外边会和border的最外边重合的,如果图片最外边的颜色很深,有看出有棱边的效果,所以为了让体验更加好, 
  133.          * 让其缩进padding px) 
  134.          */  
  135.         RectF localRectF = new RectF(padding, padding, width - padding, height - padding);  
  136.         localCanvas.drawOval(localRectF, localPaint);  
  137.         return localBitmap;  
  138.     }  
  139. }  


xml布局:

[html] view plain copy
  1. <com.xyt.ygcf.widget.CircleImageView  
  2.         xmlns:myxmlns="http://schemas.android.com/apk/res/com.xyt.yangguangchufang"  
  3.         android:id="@+id/fragment_my_image_user"  
  4.         android:layout_width="110dp"  
  5.         android:layout_height="110dp"  
  6.         android:layout_marginBottom="10dp"  
  7.         android:contentDescription="@null"  
  8.         android:scaleType="centerCrop"  
  9.         myxmlns:border_width="@dimen/circle_width"  
  10.         myxmlns:border_color="@color/f2f2f2"  
  11.         android:src="@drawable/ic_my_avar_unlogin" />  

attr文件:
[html] view plain copy
  1. <declare-styleable name="CircularImage">  
  2.        <attr name="border_width" format="dimension" />  
  3.        <attr name="border_color" format="color" />  
  4.    </declare-styleable>  

抽空还要认真研究一下canvas,理解还不是太深刻。
个人分类: Android

猜你喜欢

转载自blog.csdn.net/u011652925/article/details/80180501