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


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

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

     

    [java] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    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, null, 31);  
    79.         /** 设置drawable的大小 */  
    80.         localDrawable.setBounds(0, 0, 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
     
     在CODE上查看代码片派生到我的代码片
    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
     
     在CODE上查看代码片派生到我的代码片
    1. <declare-styleable name="CircularImage">  
    2.        <attr name="border_width" format="dimension" />  
    3.        <attr name="border_color" format="color" />  
    4.    </declare-styleable>  


    抽空还要认真研究一下canvas,理解还不是太深刻。

  • 相关阅读:
    深度学习方面的学术交流平台?
    如何用简单例子讲解 Q
    强化学习之Q-learning简介
    学完了在线课程?如何开启深度学习论文的阅读模式
    Java高级特性之枚举
    uboot启动流程
    Chromium网页Layer Tree创建过程分析
    Sql控制反转小尝试
    模拟日历计算 poj1008
    安卓零碎知识集中
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/5996437.html
Copyright © 2020-2023  润新知