Android圆形头像图Circle ImageView

来源:互联网 发布:ssm框架打印sql语句 编辑:程序博客网 时间:2024/04/28 07:45

《Android圆形头像图Circle ImageView》

需要处理的原始图(pic):


使用CircleImageView处理后的图(作为头像):


现在很多的应用都有设置头像的功能,如QQ、微信、微博等。头像有标准的四方形,也有圆形(如QQ)。现在结合他人的代码加以修改,给出一个以原始图形中心为原点,修剪图片为头像的工具类,此类

可以直接在布局文件中加载使用,比如:

[html] view plain copy
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent" >  
  5.   
  6.     <zhangphil.circle.CircleImageView  
  7.         android:id="@+id/civ"  
  8.         android:layout_width="wrap_content"  
  9.         android:layout_height="wrap_content"  
  10.         android:src="@drawable/pic" />  
  11.   
  12. </RelativeLayout>  

CircleImageView.java的完整源代码:

[java] view plain copy
  1. package zhangphil.circle;  
  2.   
  3. import android.content.Context;  
  4. import android.content.res.TypedArray;  
  5. import android.graphics.Bitmap;  
  6. import android.graphics.BitmapShader;  
  7. import android.graphics.Canvas;  
  8. import android.graphics.Color;  
  9. import android.graphics.Matrix;  
  10. import android.graphics.Paint;  
  11. import android.graphics.Paint.Align;  
  12. import android.graphics.Rect;  
  13. import android.graphics.RectF;  
  14. import android.graphics.Shader;  
  15. import android.graphics.SweepGradient;  
  16. import android.graphics.drawable.BitmapDrawable;  
  17. import android.graphics.drawable.ColorDrawable;  
  18. import android.graphics.drawable.Drawable;  
  19. import android.net.Uri;  
  20. import android.text.TextPaint;  
  21. import android.util.AttributeSet;  
  22. import android.util.FloatMath;  
  23. import android.widget.ImageView;  
  24.   
  25. /** 
  26.  * @author Phil 
  27.  * 
  28.  */  
  29. public class CircleImageView extends ImageView {  
  30.   
  31.     private static final ScaleType SCALE_TYPE = ScaleType.CENTER_CROP;  
  32.   
  33.     private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888;  
  34.     private static final int COLORDRAWABLE_DIMENSION = 2;  
  35.   
  36.     // 圆形边框的厚度默认值。  
  37.     // 如果是0,则没有天蓝色渐变的边框。  
  38.     private static final int DEFAULT_BORDER_WIDTH = 20;  
  39.   
  40.     private static final int DEFAULT_BORDER_COLOR = Color.BLACK;  
  41.   
  42.     private final RectF mDrawableRect = new RectF();  
  43.     private final RectF mBorderRect = new RectF();  
  44.   
  45.     private final Matrix mShaderMatrix = new Matrix();  
  46.     private final Paint mBitmapPaint = new Paint();  
  47.     private final Paint mBorderPaint = new Paint();  
  48.   
  49.     private int mBorderColor = DEFAULT_BORDER_COLOR;  
  50.     private int mBorderWidth = DEFAULT_BORDER_WIDTH;  
  51.   
  52.     private Bitmap mBitmap;  
  53.     private BitmapShader mBitmapShader;  
  54.     private int mBitmapWidth;  
  55.     private int mBitmapHeight;  
  56.   
  57.     private float mDrawableRadius;  
  58.     private float mBorderRadius;  
  59.   
  60.     private boolean mReady;  
  61.     private boolean mSetupPending;  
  62.     private final Paint mFlagBackgroundPaint = new Paint();  
  63.     private final TextPaint mFlagTextPaint = new TextPaint();  
  64.     private String mFlagText;  
  65.     private boolean mShowFlag = false;  
  66.     private Rect mFlagTextBounds = new Rect();  
  67.   
  68.     Shader mSweepGradient = null;  
  69.   
  70.     public CircleImageView(Context context) {  
  71.         super(context);  
  72.   
  73.         init();  
  74.     }  
  75.   
  76.     public CircleImageView(Context context, AttributeSet attrs) {  
  77.         this(context, attrs, 0);  
  78.     }  
  79.   
  80.     public CircleImageView(Context context, AttributeSet attrs, int defStyle) {  
  81.         super(context, attrs, defStyle);  
  82.   
  83.         // TypedArray a = context.obtainStyledAttributes(attrs,  
  84.         // R.styleable.CircleImageView, defStyle, 0);  
  85.         //  
  86.         // mBorderWidth =  
  87.         // a.getDimensionPixelSize(R.styleable.CircleImageView_border_width,  
  88.         // DEFAULT_BORDER_WIDTH);  
  89.         // mBorderColor = a.getColor(R.styleable.CircleImageView_border_color,  
  90.         // DEFAULT_BORDER_COLOR);  
  91.         //  
  92.         // a.recycle();  
  93.   
  94.         init();  
  95.     }  
  96.   
  97.     private void init() {  
  98.         super.setScaleType(SCALE_TYPE);  
  99.         mReady = true;  
  100.   
  101.         if (mSetupPending) {  
  102.             setup();  
  103.             mSetupPending = false;  
  104.         }  
  105.     }  
  106.   
  107.     @Override  
  108.     public ScaleType getScaleType() {  
  109.         return SCALE_TYPE;  
  110.     }  
  111.   
  112.     @Override  
  113.     public void setScaleType(ScaleType scaleType) {  
  114.         if (scaleType != SCALE_TYPE) {  
  115.             throw new IllegalArgumentException(String.format(  
  116.                     "ScaleType %s not supported.", scaleType));  
  117.         }  
  118.     }  
  119.   
  120.     @Override  
  121.     public void setAdjustViewBounds(boolean adjustViewBounds) {  
  122.         if (adjustViewBounds) {  
  123.             throw new IllegalArgumentException(  
  124.                     "adjustViewBounds not supported.");  
  125.         }  
  126.     }  
  127.   
  128.     @Override  
  129.     protected void onDraw(Canvas canvas) {  
  130.         if (getDrawable() == null) {  
  131.             return;  
  132.         }  
  133.   
  134.         canvas.drawCircle(getWidth() / 2, getHeight() / 2, mDrawableRadius,  
  135.                 mBitmapPaint);  
  136.         if (mBorderWidth != 0) {  
  137.             canvas.save();  
  138.             canvas.rotate(20, getWidth() / 2, getHeight() / 2);  
  139.             canvas.drawCircle(getWidth() / 2, getHeight() / 2, mBorderRadius,  
  140.                     mBorderPaint);  
  141.             canvas.restore();  
  142.         }  
  143.   
  144.         if (mShowFlag && mFlagText != null) {  
  145.             canvas.drawArc(mBorderRect, 40100false, mFlagBackgroundPaint);  
  146.             mFlagTextPaint.getTextBounds(mFlagText, 0, mFlagText.length(),  
  147.                     mFlagTextBounds);  
  148.             canvas.drawText(mFlagText, getWidth() / 2,  
  149.                     (3 + FloatMath.cos((float) (Math.PI * 5 / 18)))  
  150.                             * getHeight() / 4 + mFlagTextBounds.height() / 3,  
  151.                     mFlagTextPaint);  
  152.         }  
  153.   
  154.     }  
  155.   
  156.     @Override  
  157.     protected void onSizeChanged(int w, int h, int oldw, int oldh) {  
  158.         super.onSizeChanged(w, h, oldw, oldh);  
  159.         setup();  
  160.     }  
  161.   
  162.     public int getBorderColor() {  
  163.         return mBorderColor;  
  164.     }  
  165.   
  166.     public void setBorderColor(int borderColor) {  
  167.         if (borderColor == mBorderColor) {  
  168.             return;  
  169.         }  
  170.   
  171.         mBorderColor = borderColor;  
  172.         mBorderPaint.setColor(mBorderColor);  
  173.         invalidate();  
  174.     }  
  175.   
  176.     public int getBorderWidth() {  
  177.         return mBorderWidth;  
  178.     }  
  179.   
  180.     /** 
  181.      * @param borderWidth 
  182.      *            圆形的边框厚度。 
  183.      */  
  184.     public void setBorderWidth(int borderWidth) {  
  185.         if (borderWidth == mBorderWidth) {  
  186.             return;  
  187.         }  
  188.   
  189.         mBorderWidth = borderWidth;  
  190.         setup();  
  191.     }  
  192.   
  193.     @Override  
  194.     public void setImageBitmap(Bitmap bm) {  
  195.         super.setImageBitmap(bm);  
  196.         mBitmap = bm;  
  197.         setup();  
  198.     }  
  199.   
  200.     @Override  
  201.     public void setImageDrawable(Drawable drawable) {  
  202.         super.setImageDrawable(drawable);  
  203.         mBitmap = getBitmapFromDrawable(drawable);  
  204.         setup();  
  205.     }  
  206.   
  207.     @Override  
  208.     public void setImageResource(int resId) {  
  209.         super.setImageResource(resId);  
  210.         mBitmap = getBitmapFromDrawable(getDrawable());  
  211.         setup();  
  212.     }  
  213.   
  214.     @Override  
  215.     public void setImageURI(Uri uri) {  
  216.         super.setImageURI(uri);  
  217.         mBitmap = getBitmapFromDrawable(getDrawable());  
  218.         setup();  
  219.     }  
  220.   
  221.     private Bitmap getBitmapFromDrawable(Drawable drawable) {  
  222.         if (drawable == null) {  
  223.             return null;  
  224.         }  
  225.   
  226.         if (drawable instanceof BitmapDrawable) {  
  227.             return ((BitmapDrawable) drawable).getBitmap();  
  228.         }  
  229.   
  230.         try {  
  231.             Bitmap bitmap;  
  232.   
  233.             if (drawable instanceof ColorDrawable) {  
  234.                 bitmap = Bitmap.createBitmap(COLORDRAWABLE_DIMENSION,  
  235.                         COLORDRAWABLE_DIMENSION, BITMAP_CONFIG);  
  236.             } else {  
  237.                 bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(),  
  238.                         drawable.getIntrinsicHeight(), BITMAP_CONFIG);  
  239.             }  
  240.   
  241.             Canvas canvas = new Canvas(bitmap);  
  242.             drawable.setBounds(00, canvas.getWidth(), canvas.getHeight());  
  243.             drawable.draw(canvas);  
  244.             return bitmap;  
  245.         } catch (OutOfMemoryError e) {  
  246.             return null;  
  247.         }  
  248.     }  
  249.   
  250.     private void setup() {  
  251.         if (!mReady) {  
  252.             mSetupPending = true;  
  253.             return;  
  254.         }  
  255.   
  256.         if (mBitmap == null) {  
  257.             return;  
  258.         }  
  259.   
  260.         mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP,  
  261.                 Shader.TileMode.CLAMP);  
  262.   
  263.         mBitmapPaint.setAntiAlias(true);  
  264.         mBitmapPaint.setShader(mBitmapShader);  
  265.   
  266.         mBorderPaint.setStyle(Paint.Style.STROKE);  
  267.         mBorderPaint.setAntiAlias(true);  
  268.         mBorderPaint.setColor(mBorderColor);  
  269.         mBorderPaint.setStrokeWidth(mBorderWidth);  
  270.   
  271.         mBitmapHeight = mBitmap.getHeight();  
  272.         mBitmapWidth = mBitmap.getWidth();  
  273.   
  274.         mBorderRect.set(00, getWidth(), getHeight());  
  275.         mBorderRadius = Math.min((mBorderRect.height() - mBorderWidth) / 2,  
  276.                 (mBorderRect.width() - mBorderWidth) / 2);  
  277.   
  278.         mDrawableRect.set(mBorderWidth, mBorderWidth, mBorderRect.width()  
  279.                 - mBorderWidth, mBorderRect.height() - mBorderWidth);  
  280.         mDrawableRadius = Math.min(mDrawableRect.height() / 2,  
  281.                 mDrawableRect.width() / 2);  
  282.   
  283.         mFlagBackgroundPaint.setColor(Color.BLACK & 0x66FFFFFF);  
  284.         mFlagBackgroundPaint.setFlags(TextPaint.ANTI_ALIAS_FLAG);  
  285.   
  286.         mFlagTextPaint.setFlags(TextPaint.ANTI_ALIAS_FLAG);  
  287.         mFlagTextPaint.setTextAlign(Align.CENTER);  
  288.         mFlagTextPaint.setColor(Color.WHITE);  
  289.         mFlagTextPaint  
  290.                 .setTextSize(getResources().getDisplayMetrics().density * 18);  
  291.   
  292.         mSweepGradient = new SweepGradient(getWidth() / 2, getHeight() / 2,  
  293.                 new int[] { Color.rgb(255255255), Color.rgb(1209255) },  
  294.                 null);  
  295.   
  296.         mBorderPaint.setShader(mSweepGradient);  
  297.   
  298.         updateShaderMatrix();  
  299.         invalidate();  
  300.     }  
  301.   
  302.     private void updateShaderMatrix() {  
  303.         float scale;  
  304.         float dx = 0;  
  305.         float dy = 0;  
  306.   
  307.         mShaderMatrix.set(null);  
  308.   
  309.         if (mBitmapWidth * mDrawableRect.height() > mDrawableRect.width()  
  310.                 * mBitmapHeight) {  
  311.             scale = mDrawableRect.height() / (float) mBitmapHeight;  
  312.             dx = (mDrawableRect.width() - mBitmapWidth * scale) * 0.5f;  
  313.         } else {  
  314.             scale = mDrawableRect.width() / (float) mBitmapWidth;  
  315.             dy = (mDrawableRect.height() - mBitmapHeight * scale) * 0.5f;  
  316.         }  
  317.   
  318.         mShaderMatrix.setScale(scale, scale);  
  319.         mShaderMatrix.postTranslate((int) (dx + 0.5f) + mBorderWidth,  
  320.                 (int) (dy + 0.5f) + mBorderWidth);  
  321.   
  322.         mBitmapShader.setLocalMatrix(mShaderMatrix);  
  323.     }  
  324.   
  325.     public void setShowFlag(boolean show) {  
  326.         mShowFlag = show;  
  327.         invalidate();  
  328.     }  
  329.   
  330.     public void setFlagText(String text) {  
  331.         mFlagText = text;  
  332.         invalidate();  
  333.     }  
  334. }  
0 0
原创粉丝点击