画圆的类:
CircleImageView ,有一个不好的地方,第一次加载应用程序的时候,不显示图片。
RoundImageView 就更好的解决了这个问题。
1 public class CircleImageView extends ImageView { 2 3 private static final ScaleType SCALE_TYPE = ScaleType.CENTER_CROP; 4 5 private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888; 6 private static final int COLORDRAWABLE_DIMENSION = 2; 7 8 private static final int DEFAULT_BORDER_WIDTH = 0; 9 private static final int DEFAULT_BORDER_COLOR = Color.BLACK; 10 11 private final RectF mDrawableRect = new RectF(); 12 private final RectF mBorderRect = new RectF(); 13 14 private final Matrix mShaderMatrix = new Matrix(); 15 private final Paint mBitmapPaint = new Paint(); 16 private final Paint mBorderPaint = new Paint(); 17 18 private int mBorderColor = DEFAULT_BORDER_COLOR; 19 private int mBorderWidth = DEFAULT_BORDER_WIDTH; 20 21 private Bitmap mBitmap; 22 private BitmapShader mBitmapShader; 23 private int mBitmapWidth; 24 private int mBitmapHeight; 25 26 private float mDrawableRadius; 27 private float mBorderRadius; 28 29 private ColorFilter mColorFilter; 30 31 private boolean mReady; 32 private boolean mSetupPending; 33 34 public CircleImageView(Context context) { 35 super(context); 36 37 init(); 38 } 39 40 public CircleImageView(Context context, AttributeSet attrs) { 41 this(context, attrs, 0); 42 } 43 44 public CircleImageView(Context context, AttributeSet attrs, int defStyle) { 45 super(context, attrs, defStyle); 46 47 TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircleImageView, defStyle, 0); 48 49 mBorderWidth = a.getDimensionPixelSize(R.styleable.CircleImageView_border_width, DEFAULT_BORDER_WIDTH); 50 mBorderColor = a.getColor(R.styleable.CircleImageView_border_color, DEFAULT_BORDER_COLOR); 51 52 a.recycle(); 53 54 init(); 55 } 56 57 private void init() { 58 super.setScaleType(SCALE_TYPE); 59 mReady = true; 60 61 if (mSetupPending) { 62 setup(); 63 mSetupPending = false; 64 } 65 } 66 67 @Override 68 public ScaleType getScaleType() { 69 return SCALE_TYPE; 70 } 71 72 @Override 73 public void setScaleType(ScaleType scaleType) { 74 if (scaleType != SCALE_TYPE) { 75 throw new IllegalArgumentException(String.format("ScaleType %s not supported.", scaleType)); 76 } 77 } 78 79 @Override 80 public void setAdjustViewBounds(boolean adjustViewBounds) { 81 if (adjustViewBounds) { 82 throw new IllegalArgumentException("adjustViewBounds not supported."); 83 } 84 } 85 86 @Override 87 protected void onDraw(Canvas canvas) { 88 if (getDrawable() == null) { 89 return; 90 } 91 92 canvas.drawCircle(getWidth() / 2, getHeight() / 2, mDrawableRadius, mBitmapPaint); 93 if (mBorderWidth != 0) { 94 canvas.drawCircle(getWidth() / 2, getHeight() / 2, mBorderRadius, mBorderPaint); 95 } 96 } 97 98 @Override 99 protected void onSizeChanged(int w, int h, int oldw, int oldh) { 100 super.onSizeChanged(w, h, oldw, oldh); 101 setup(); 102 } 103 104 public int getBorderColor() { 105 return mBorderColor; 106 } 107 108 public void setBorderColor(int borderColor) { 109 if (borderColor == mBorderColor) { 110 return; 111 } 112 113 mBorderColor = borderColor; 114 mBorderPaint.setColor(mBorderColor); 115 invalidate(); 116 } 117 118 public int getBorderWidth() { 119 return mBorderWidth; 120 } 121 122 public void setBorderWidth(int borderWidth) { 123 if (borderWidth == mBorderWidth) { 124 return; 125 } 126 127 mBorderWidth = borderWidth; 128 setup(); 129 } 130 131 @Override 132 public void setImageBitmap(Bitmap bm) { 133 super.setImageBitmap(bm); 134 mBitmap = bm; 135 setup(); 136 } 137 138 @Override 139 public void setImageDrawable(Drawable drawable) { 140 super.setImageDrawable(drawable); 141 mBitmap = getBitmapFromDrawable(drawable); 142 setup(); 143 } 144 145 @Override 146 public void setImageResource(int resId) { 147 super.setImageResource(resId); 148 mBitmap = getBitmapFromDrawable(getDrawable()); 149 setup(); 150 } 151 152 @Override 153 public void setImageURI(Uri uri) { 154 super.setImageURI(uri); 155 mBitmap = getBitmapFromDrawable(getDrawable()); 156 setup(); 157 } 158 159 @Override 160 public void setColorFilter(ColorFilter cf) { 161 if (cf == mColorFilter) { 162 return; 163 } 164 165 mColorFilter = cf; 166 mBitmapPaint.setColorFilter(mColorFilter); 167 invalidate(); 168 } 169 170 private Bitmap getBitmapFromDrawable(Drawable drawable) { 171 if (drawable == null) { 172 return null; 173 } 174 175 if (drawable instanceof BitmapDrawable) { 176 return ((BitmapDrawable) drawable).getBitmap(); 177 } 178 179 try { 180 Bitmap bitmap; 181 182 if (drawable instanceof ColorDrawable) { 183 bitmap = Bitmap.createBitmap(COLORDRAWABLE_DIMENSION, COLORDRAWABLE_DIMENSION, BITMAP_CONFIG); 184 } else { 185 bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), BITMAP_CONFIG); 186 } 187 188 Canvas canvas = new Canvas(bitmap); 189 drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); 190 drawable.draw(canvas); 191 return bitmap; 192 } catch (OutOfMemoryError e) { 193 return null; 194 } 195 } 196 197 private void setup() { 198 if (!mReady) { 199 mSetupPending = true; 200 return; 201 } 202 203 if (mBitmap == null) { 204 return; 205 } 206 207 mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); 208 209 mBitmapPaint.setAntiAlias(true); 210 mBitmapPaint.setShader(mBitmapShader); 211 212 mBorderPaint.setStyle(Paint.Style.STROKE); 213 mBorderPaint.setAntiAlias(true); 214 mBorderPaint.setColor(mBorderColor); 215 mBorderPaint.setStrokeWidth(mBorderWidth); 216 217 mBitmapHeight = mBitmap.getHeight(); 218 mBitmapWidth = mBitmap.getWidth(); 219 220 mBorderRect.set(0, 0, getWidth(), getHeight()); 221 mBorderRadius = Math.min((mBorderRect.height() - mBorderWidth) / 2, (mBorderRect.width() - mBorderWidth) / 2); 222 223 mDrawableRect.set(mBorderWidth, mBorderWidth, mBorderRect.width() - mBorderWidth, mBorderRect.height() - mBorderWidth); 224 mDrawableRadius = Math.min(mDrawableRect.height() / 2, mDrawableRect.width() / 2); 225 226 updateShaderMatrix(); 227 invalidate(); 228 } 229 230 private void updateShaderMatrix() { 231 float scale; 232 float dx = 0; 233 float dy = 0; 234 235 mShaderMatrix.set(null); 236 237 if (mBitmapWidth * mDrawableRect.height() > mDrawableRect.width() * mBitmapHeight) { 238 scale = mDrawableRect.height() / (float) mBitmapHeight; 239 dx = (mDrawableRect.width() - mBitmapWidth * scale) * 0.5f; 240 } else { 241 scale = mDrawableRect.width() / (float) mBitmapWidth; 242 dy = (mDrawableRect.height() - mBitmapHeight * scale) * 0.5f; 243 } 244 245 mShaderMatrix.setScale(scale, scale); 246 mShaderMatrix.postTranslate((int) (dx + 0.5f) + mBorderWidth, (int) (dy + 0.5f) + mBorderWidth); 247 248 mBitmapShader.setLocalMatrix(mShaderMatrix); 249 } 250 251 }
XMl中:(注意:xml中要设置命名空间 xmlns:app(自己取名)="http://schemas.android.com/apk/res/主包名")
只能在xml中用src属性有效。用代码动态定义控件无效。
1 <com.qianfeng.xingshuaieducation.ui.CircleImageView 2 android:id="@+id/imgv__header_lvitem_shequ" 3 android:layout_width="60dp" 4 android:layout_height="60dp" 5 app:border_width="2dp" 6 app:border_color="#FF000000" 7 android:src="@drawable/ic_launcher" />
attrs, R.styleable.CircleImageView
1 <resources> 2 <declare-styleable name="CircleImageView"> 3 <attr name="border_width" format="dimension" /> 4 <attr name="border_color" format="color" /> 5 </declare-styleable> 6 </resources>