原形头像

  1 import android.content.Context;
  2 import android.content.res.TypedArray;
  3 import android.graphics.Bitmap;
  4 import android.graphics.BitmapShader;
  5 import android.graphics.Canvas;
  6 import android.graphics.Color;
  7 import android.graphics.Matrix;
  8 import android.graphics.Paint;
  9 import android.graphics.RectF;
 10 import android.graphics.Shader;
 11 import android.graphics.drawable.BitmapDrawable;
 12 import android.graphics.drawable.ColorDrawable;
 13 import android.graphics.drawable.Drawable;
 14 import android.util.AttributeSet;
 15 import android.widget.ImageView;
 16 
 17  
 18 public class CircleImageView extends ImageView {
 19 
 20     private static final ScaleType SCALE_TYPE = ScaleType.CENTER_CROP;
 21 
 22     private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888;
 23     private static final int COLORDRAWABLE_DIMENSION = 1;
 24 
 25     private static final int DEFAULT_BORDER_WIDTH = 0;
 26     private static final int DEFAULT_BORDER_COLOR = Color.BLACK;
 27 
 28     private final RectF mDrawableRect = new RectF();
 29     private final RectF mBorderRect = new RectF();
 30 
 31     private final Matrix mShaderMatrix = new Matrix();
 32     private final Paint mBitmapPaint = new Paint();
 33     private final Paint mBorderPaint = new Paint();
 34 
 35     private int mBorderColor = DEFAULT_BORDER_COLOR;
 36     private int mBorderWidth = DEFAULT_BORDER_WIDTH;
 37 
 38     private Bitmap mBitmap;
 39     private BitmapShader mBitmapShader;
 40     private int mBitmapWidth;
 41     private int mBitmapHeight;
 42 
 43     private float mDrawableRadius;
 44     private float mBorderRadius;
 45 
 46     private boolean mReady;
 47     private boolean mSetupPending;
 48 
 49     public CircleImageView(Context context) {
 50         super(context);
 51     }
 52 
 53     public CircleImageView(Context context, AttributeSet attrs) {
 54         this(context, attrs, 0);
 55     }
 56 
 57     public CircleImageView(Context context, AttributeSet attrs, int defStyle) {
 58         super(context, attrs, defStyle);
 59         super.setScaleType(SCALE_TYPE);
 60 
 61         TypedArray a = context.obtainStyledAttributes(attrs,
 62                 R.styleable.CircleImageView, defStyle, 0);
 63 
 64         mBorderWidth = a.getDimensionPixelSize(
 65                 R.styleable.CircleImageView_border_width, DEFAULT_BORDER_WIDTH);
 66         mBorderColor = a.getColor(R.styleable.CircleImageView_border_color,
 67                 DEFAULT_BORDER_COLOR);
 68 
 69         a.recycle();
 70 
 71         mReady = true;
 72 
 73         if (mSetupPending) {
 74             setup();
 75             mSetupPending = false;
 76         }
 77     }
 78 
 79     @Override
 80     public ScaleType getScaleType() {
 81         return SCALE_TYPE;
 82     }
 83 
 84     @Override
 85     public void setScaleType(ScaleType scaleType) {
 86         if (scaleType != SCALE_TYPE) {
 87             throw new IllegalArgumentException(String.format(
 88                     "ScaleType %s not supported.", scaleType));
 89         }
 90     }
 91 
 92     @Override
 93     protected void onDraw(Canvas canvas) {
 94         if (getDrawable() == null) {
 95             return;
 96         }
 97 
 98         canvas.drawCircle(getWidth() / 2, getHeight() / 2, mDrawableRadius,
 99                 mBitmapPaint);
100         if (mBorderWidth != 0) {
101             canvas.drawCircle(getWidth() / 2, getHeight() / 2, mBorderRadius,
102                     mBorderPaint);
103         }
104     }
105 
106     @Override
107     protected void onSizeChanged(int w, int h, int oldw, int oldh) {
108         super.onSizeChanged(w, h, oldw, oldh);
109         setup();
110     }
111 
112     public int getBorderColor() {
113         return mBorderColor;
114     }
115 
116     public void setBorderColor(int borderColor) {
117         if (borderColor == mBorderColor) {
118             return;
119         }
120 
121         mBorderColor = borderColor;
122         mBorderPaint.setColor(mBorderColor);
123         invalidate();
124     }
125 
126     public int getBorderWidth() {
127         return mBorderWidth;
128     }
129 
130     public void setBorderWidth(int borderWidth) {
131         if (borderWidth == mBorderWidth) {
132             return;
133         }
134 
135         mBorderWidth = borderWidth;
136         setup();
137     }
138 
139     @Override
140     public void setImageBitmap(Bitmap bm) {
141         super.setImageBitmap(bm);
142         mBitmap = bm;
143         setup();
144     }
145 
146     @Override
147     public void setImageDrawable(Drawable drawable) {
148         super.setImageDrawable(drawable);
149         mBitmap = getBitmapFromDrawable(drawable);
150         setup();
151     }
152 
153     @Override
154     public void setImageResource(int resId) {
155         super.setImageResource(resId);
156         mBitmap = getBitmapFromDrawable(getDrawable());
157         setup();
158     }
159 
160     private Bitmap getBitmapFromDrawable(Drawable drawable) {
161         if (drawable == null) {
162             return null;
163         }
164 
165         if (drawable instanceof BitmapDrawable) {
166             return ((BitmapDrawable) drawable).getBitmap();
167         }
168 
169         try {
170             Bitmap bitmap;
171 
172             if (drawable instanceof ColorDrawable) {
173                 bitmap = Bitmap.createBitmap(COLORDRAWABLE_DIMENSION,
174                         COLORDRAWABLE_DIMENSION, BITMAP_CONFIG);
175             } else {
176                 bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(),
177                         drawable.getIntrinsicHeight(), BITMAP_CONFIG);
178             }
179 
180             Canvas canvas = new Canvas(bitmap);
181             drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
182             drawable.draw(canvas);
183             return bitmap;
184         } catch (OutOfMemoryError e) {
185             return null;
186         }
187     }
188 
189     private void setup() {
190         if (!mReady) {
191             mSetupPending = true;
192             return;
193         }
194 
195         if (mBitmap == null) {
196             return;
197         }
198 
199         mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP,
200                 Shader.TileMode.CLAMP);
201 
202         mBitmapPaint.setAntiAlias(true);
203         mBitmapPaint.setShader(mBitmapShader);
204 
205         mBorderPaint.setStyle(Paint.Style.STROKE);
206         mBorderPaint.setAntiAlias(true);
207         mBorderPaint.setColor(mBorderColor);
208         mBorderPaint.setStrokeWidth(mBorderWidth);
209 
210         mBitmapHeight = mBitmap.getHeight();
211         mBitmapWidth = mBitmap.getWidth();
212 
213         mBorderRect.set(0, 0, getWidth(), getHeight());
214         mBorderRadius = Math.min((mBorderRect.height() - mBorderWidth) / 2,
215                 (mBorderRect.width() - mBorderWidth) / 2);
216 
217         mDrawableRect.set(mBorderWidth, mBorderWidth, mBorderRect.width()
218                 - mBorderWidth, mBorderRect.height() - mBorderWidth);
219         mDrawableRadius = Math.min(mDrawableRect.height() / 2,
220                 mDrawableRect.width() / 2);
221 
222         updateShaderMatrix();
223         invalidate();
224     }
225 
226     private void updateShaderMatrix() {
227         float scale;
228         float dx = 0;
229         float dy = 0;
230 
231         mShaderMatrix.set(null);
232 
233         if (mBitmapWidth * mDrawableRect.height() > mDrawableRect.width()
234                 * mBitmapHeight) {
235             scale = mDrawableRect.height() / (float) mBitmapHeight;
236             dx = (mDrawableRect.width() - mBitmapWidth * scale) * 0.5f;
237         } else {
238             scale = mDrawableRect.width() / (float) mBitmapWidth;
239             dy = (mDrawableRect.height() - mBitmapHeight * scale) * 0.5f;
240         }
241 
242         mShaderMatrix.setScale(scale, scale);
243         mShaderMatrix.postTranslate((int) (dx + 0.5f) + mBorderWidth,
244                 (int) (dy + 0.5f) + mBorderWidth);
245 
246         mBitmapShader.setLocalMatrix(mShaderMatrix);
247     }
248 
249 }

 

1 <com.sample.CircleImageView
2        android:layout_width="80dp"
3        android:layout_height="80dp"
4        android:layout_marginLeft="40dp"
5        android:scaleType="centerCrop"
6        android:src="@drawable/charming" />

 

posted on 2015-01-14 19:18  大米稀饭  阅读(211)  评论(0编辑  收藏  举报