原形头像

  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" />

 

你可能感兴趣的:(原形头像)