首页 > 代码库 > 安卓自定义圆形图片控件的使用(hdodenhof/CircleImageView)
安卓自定义圆形图片控件的使用(hdodenhof/CircleImageView)
控件的来源:https://github.com/hdodenhof/CircleImageView
感兴趣的可以去看看,我只说一下怎么使用:
效果图:
在自己的项目中使用的话,需要写一个类class CircleImageView extends ImageView :
具体如下,只是使用的话,复制过来就好,注意改一下包名:
1 package de.hdodenhof.circleimageview; 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.ColorFilter; 10 import android.graphics.Matrix; 11 import android.graphics.Paint; 12 import android.graphics.RectF; 13 import android.graphics.Shader; 14 import android.graphics.drawable.BitmapDrawable; 15 import android.graphics.drawable.ColorDrawable; 16 import android.graphics.drawable.Drawable; 17 import android.net.Uri; 18 import android.support.annotation.ColorInt; 19 import android.support.annotation.ColorRes; 20 import android.support.annotation.DrawableRes; 21 import android.util.AttributeSet; 22 import android.widget.ImageView; 23 24 public class CircleImageView extends ImageView { 25 26 private static final ScaleType SCALE_TYPE = ScaleType.CENTER_CROP; 27 28 private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888; 29 private static final int COLORDRAWABLE_DIMENSION = 2; 30 31 private static final int DEFAULT_BORDER_WIDTH = 0; 32 private static final int DEFAULT_BORDER_COLOR = Color.BLACK; 33 private static final int DEFAULT_FILL_COLOR = Color.TRANSPARENT; 34 private static final boolean DEFAULT_BORDER_OVERLAY = false; 35 36 private final RectF mDrawableRect = new RectF(); 37 private final RectF mBorderRect = new RectF(); 38 39 private final Matrix mShaderMatrix = new Matrix(); 40 private final Paint mBitmapPaint = new Paint(); 41 private final Paint mBorderPaint = new Paint(); 42 private final Paint mFillPaint = new Paint(); 43 44 private int mBorderColor = DEFAULT_BORDER_COLOR; 45 private int mBorderWidth = DEFAULT_BORDER_WIDTH; 46 private int mFillColor = DEFAULT_FILL_COLOR; 47 48 private Bitmap mBitmap; 49 private BitmapShader mBitmapShader; 50 private int mBitmapWidth; 51 private int mBitmapHeight; 52 53 private float mDrawableRadius; 54 private float mBorderRadius; 55 56 private ColorFilter mColorFilter; 57 58 private boolean mReady; 59 private boolean mSetupPending; 60 private boolean mBorderOverlay; 61 private boolean mDisableCircularTransformation; 62 63 public CircleImageView(Context context) { 64 super(context); 65 66 init(); 67 } 68 69 public CircleImageView(Context context, AttributeSet attrs) { 70 this(context, attrs, 0); 71 } 72 73 public CircleImageView(Context context, AttributeSet attrs, int defStyle) { 74 super(context, attrs, defStyle); 75 76 TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircleImageView, defStyle, 0); 77 78 mBorderWidth = a.getDimensionPixelSize(R.styleable.CircleImageView_civ_border_width, DEFAULT_BORDER_WIDTH); 79 mBorderColor = a.getColor(R.styleable.CircleImageView_civ_border_color, DEFAULT_BORDER_COLOR); 80 mBorderOverlay = a.getBoolean(R.styleable.CircleImageView_civ_border_overlay, DEFAULT_BORDER_OVERLAY); 81 mFillColor = a.getColor(R.styleable.CircleImageView_civ_fill_color, DEFAULT_FILL_COLOR); 82 83 a.recycle(); 84 85 init(); 86 } 87 88 private void init() { 89 super.setScaleType(SCALE_TYPE); 90 mReady = true; 91 92 if (mSetupPending) { 93 setup(); 94 mSetupPending = false; 95 } 96 } 97 98 @Override 99 public ScaleType getScaleType() {100 return SCALE_TYPE;101 }102 103 @Override104 public void setScaleType(ScaleType scaleType) {105 if (scaleType != SCALE_TYPE) {106 throw new IllegalArgumentException(String.format("ScaleType %s not supported.", scaleType));107 }108 }109 110 @Override111 public void setAdjustViewBounds(boolean adjustViewBounds) {112 if (adjustViewBounds) {113 throw new IllegalArgumentException("adjustViewBounds not supported.");114 }115 }116 117 @Override118 protected void onDraw(Canvas canvas) {119 if (mDisableCircularTransformation) {120 super.onDraw(canvas);121 return;122 }123 124 if (mBitmap == null) {125 return;126 }127 128 if (mFillColor != Color.TRANSPARENT) {129 canvas.drawCircle(mDrawableRect.centerX(), mDrawableRect.centerY(), mDrawableRadius, mFillPaint);130 }131 canvas.drawCircle(mDrawableRect.centerX(), mDrawableRect.centerY(), mDrawableRadius, mBitmapPaint);132 if (mBorderWidth > 0) {133 canvas.drawCircle(mBorderRect.centerX(), mBorderRect.centerY(), mBorderRadius, mBorderPaint);134 }135 }136 137 @Override138 protected void onSizeChanged(int w, int h, int oldw, int oldh) {139 super.onSizeChanged(w, h, oldw, oldh);140 setup();141 }142 143 @Override144 public void setPadding(int left, int top, int right, int bottom) {145 super.setPadding(left, top, right, bottom);146 setup();147 }148 149 @Override150 public void setPaddingRelative(int start, int top, int end, int bottom) {151 super.setPaddingRelative(start, top, end, bottom);152 setup();153 }154 155 public int getBorderColor() {156 return mBorderColor;157 }158 159 public void setBorderColor(@ColorInt int borderColor) {160 if (borderColor == mBorderColor) {161 return;162 }163 164 mBorderColor = borderColor;165 mBorderPaint.setColor(mBorderColor);166 invalidate();167 }168 169 /**170 * @deprecated Use {@link #setBorderColor(int)} instead171 */172 @Deprecated173 public void setBorderColorResource(@ColorRes int borderColorRes) {174 setBorderColor(getContext().getResources().getColor(borderColorRes));175 }176 177 /**178 * Return the color drawn behind the circle-shaped drawable.179 *180 * @return The color drawn behind the drawable181 *182 * @deprecated Fill color support is going to be removed in the future183 */184 @Deprecated185 public int getFillColor() {186 return mFillColor;187 }188 189 /**190 * Set a color to be drawn behind the circle-shaped drawable. Note that191 * this has no effect if the drawable is opaque or no drawable is set.192 *193 * @param fillColor The color to be drawn behind the drawable194 *195 * @deprecated Fill color support is going to be removed in the future196 */197 @Deprecated198 public void setFillColor(@ColorInt int fillColor) {199 if (fillColor == mFillColor) {200 return;201 }202 203 mFillColor = fillColor;204 mFillPaint.setColor(fillColor);205 invalidate();206 }207 208 /**209 * Set a color to be drawn behind the circle-shaped drawable. Note that210 * this has no effect if the drawable is opaque or no drawable is set.211 *212 * @param fillColorRes The color resource to be resolved to a color and213 * drawn behind the drawable214 *215 * @deprecated Fill color support is going to be removed in the future216 */217 @Deprecated218 public void setFillColorResource(@ColorRes int fillColorRes) {219 setFillColor(getContext().getResources().getColor(fillColorRes));220 }221 222 public int getBorderWidth() {223 return mBorderWidth;224 }225 226 public void setBorderWidth(int borderWidth) {227 if (borderWidth == mBorderWidth) {228 return;229 }230 231 mBorderWidth = borderWidth;232 setup();233 }234 235 public boolean isBorderOverlay() {236 return mBorderOverlay;237 }238 239 public void setBorderOverlay(boolean borderOverlay) {240 if (borderOverlay == mBorderOverlay) {241 return;242 }243 244 mBorderOverlay = borderOverlay;245 setup();246 }247 248 public boolean isDisableCircularTransformation() {249 return mDisableCircularTransformation;250 }251 252 public void setDisableCircularTransformation(boolean disableCircularTransformation) {253 if (mDisableCircularTransformation == disableCircularTransformation) {254 return;255 }256 257 mDisableCircularTransformation = disableCircularTransformation;258 initializeBitmap();259 }260 261 @Override262 public void setImageBitmap(Bitmap bm) {263 super.setImageBitmap(bm);264 initializeBitmap();265 }266 267 @Override268 public void setImageDrawable(Drawable drawable) {269 super.setImageDrawable(drawable);270 initializeBitmap();271 }272 273 @Override274 public void setImageResource(@DrawableRes int resId) {275 super.setImageResource(resId);276 initializeBitmap();277 }278 279 @Override280 public void setImageURI(Uri uri) {281 super.setImageURI(uri);282 initializeBitmap();283 }284 285 @Override286 public void setColorFilter(ColorFilter cf) {287 if (cf == mColorFilter) {288 return;289 }290 291 mColorFilter = cf;292 applyColorFilter();293 invalidate();294 }295 296 @Override297 public ColorFilter getColorFilter() {298 return mColorFilter;299 }300 301 private void applyColorFilter() {302 if (mBitmapPaint != null) {303 mBitmapPaint.setColorFilter(mColorFilter);304 }305 }306 307 private Bitmap getBitmapFromDrawable(Drawable drawable) {308 if (drawable == null) {309 return null;310 }311 312 if (drawable instanceof BitmapDrawable) {313 return ((BitmapDrawable) drawable).getBitmap();314 }315 316 try {317 Bitmap bitmap;318 319 if (drawable instanceof ColorDrawable) {320 bitmap = Bitmap.createBitmap(COLORDRAWABLE_DIMENSION, COLORDRAWABLE_DIMENSION, BITMAP_CONFIG);321 } else {322 bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), BITMAP_CONFIG);323 }324 325 Canvas canvas = new Canvas(bitmap);326 drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());327 drawable.draw(canvas);328 return bitmap;329 } catch (Exception e) {330 e.printStackTrace();331 return null;332 }333 }334 335 private void initializeBitmap() {336 if (mDisableCircularTransformation) {337 mBitmap = null;338 } else {339 mBitmap = getBitmapFromDrawable(getDrawable());340 }341 setup();342 }343 344 private void setup() {345 if (!mReady) {346 mSetupPending = true;347 return;348 }349 350 if (getWidth() == 0 && getHeight() == 0) {351 return;352 }353 354 if (mBitmap == null) {355 invalidate();356 return;357 }358 359 mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);360 361 mBitmapPaint.setAntiAlias(true);362 mBitmapPaint.setShader(mBitmapShader);363 364 mBorderPaint.setStyle(Paint.Style.STROKE);365 mBorderPaint.setAntiAlias(true);366 mBorderPaint.setColor(mBorderColor);367 mBorderPaint.setStrokeWidth(mBorderWidth);368 369 mFillPaint.setStyle(Paint.Style.FILL);370 mFillPaint.setAntiAlias(true);371 mFillPaint.setColor(mFillColor);372 373 mBitmapHeight = mBitmap.getHeight();374 mBitmapWidth = mBitmap.getWidth();375 376 mBorderRect.set(calculateBounds());377 mBorderRadius = Math.min((mBorderRect.height() - mBorderWidth) / 2.0f, (mBorderRect.width() - mBorderWidth) / 2.0f);378 379 mDrawableRect.set(mBorderRect);380 if (!mBorderOverlay && mBorderWidth > 0) {381 mDrawableRect.inset(mBorderWidth - 1.0f, mBorderWidth - 1.0f);382 }383 mDrawableRadius = Math.min(mDrawableRect.height() / 2.0f, mDrawableRect.width() / 2.0f);384 385 applyColorFilter();386 updateShaderMatrix();387 invalidate();388 }389 390 private RectF calculateBounds() {391 int availableWidth = getWidth() - getPaddingLeft() - getPaddingRight();392 int availableHeight = getHeight() - getPaddingTop() - getPaddingBottom();393 394 int sideLength = Math.min(availableWidth, availableHeight);395 396 float left = getPaddingLeft() + (availableWidth - sideLength) / 2f;397 float top = getPaddingTop() + (availableHeight - sideLength) / 2f;398 399 return new RectF(left, top, left + sideLength, top + sideLength);400 }401 402 private void updateShaderMatrix() {403 float scale;404 float dx = 0;405 float dy = 0;406 407 mShaderMatrix.set(null);408 409 if (mBitmapWidth * mDrawableRect.height() > mDrawableRect.width() * mBitmapHeight) {410 scale = mDrawableRect.height() / (float) mBitmapHeight;411 dx = (mDrawableRect.width() - mBitmapWidth * scale) * 0.5f;412 } else {413 scale = mDrawableRect.width() / (float) mBitmapWidth;414 dy = (mDrawableRect.height() - mBitmapHeight * scale) * 0.5f;415 }416 417 mShaderMatrix.setScale(scale, scale);418 mShaderMatrix.postTranslate((int) (dx + 0.5f) + mDrawableRect.left, (int) (dy + 0.5f) + mDrawableRect.top);419 420 mBitmapShader.setLocalMatrix(mShaderMatrix);421 }422 423 }
到attr.xml中declare-styleable申明自定义控件属性
文件定义在res/values/attr.xml:
1 <?xml version="1.0" encoding="utf-8"?>2 <resources>3 <declare-styleable name="CircleImageView">4 <attr name="civ_border_width" format="dimension" />5 <attr name="civ_border_color" format="color" />6 <attr name="civ_border_overlay" format="boolean" />7 <attr name="civ_fill_color" format="color" />8 </declare-styleable>9 </resources>
在Gradle中添加(注意更改成自己的包名):
1 dependencies {2 ...3 compile ‘de.hdodenhof:circleimageview:2.1.0‘4 }
然后就能使用了
1 <de.hdodenhof.circleimageview.CircleImageView2 android:layout_width="160dp"3 android:layout_height="160dp"4 android:layout_centerInParent="true"5 android:src="@drawable/hugh"6 app:civ_border_width="2dp"7 app:civ_border_color="@color/dark" />
和一般的控件使用方式是相同的。
安卓自定义圆形图片控件的使用(hdodenhof/CircleImageView)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。