CircleImageView的使用

​ 在安卓开发中,我们常常会碰到一些圆形图片控件的困扰,而选择一款方便的圆形图片控件便成为了提高开发效率的有效手段,下面我推荐一款github上的项目,也是我本人经常使用的一款控件,因为用的比较多,随mark下来以方便下次使用

项目地址:

https://github.com/hdodenhof/CircleImageView

1,引入代码文件:

代码如下:

package com.example.myapplication;import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.support.annotation.ColorInt;
import android.support.annotation.ColorRes;
import android.support.annotation.DrawableRes;
import android.util.AttributeSet;
import android.widget.ImageView;public class CircleImageView extends android.support.v7.widget.AppCompatImageView {private static final ScaleType SCALE_TYPE = ScaleType.CENTER_CROP;private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888;private static final int COLORDRAWABLE_DIMENSION = 2;private static final int DEFAULT_BORDER_WIDTH = 0;private static final int DEFAULT_BORDER_COLOR = Color.BLACK;private static final int DEFAULT_FILL_COLOR = Color.TRANSPARENT;private static final boolean DEFAULT_BORDER_OVERLAY = false;private final RectF mDrawableRect = new RectF();private final RectF mBorderRect = new RectF();private final Matrix mShaderMatrix = new Matrix();private final Paint mBitmapPaint = new Paint();private final Paint mBorderPaint = new Paint();private final Paint mFillPaint = new Paint();private int mBorderColor = DEFAULT_BORDER_COLOR;private int mBorderWidth = DEFAULT_BORDER_WIDTH;private int mFillColor = DEFAULT_FILL_COLOR;private Bitmap mBitmap;private BitmapShader mBitmapShader;private int mBitmapWidth;private int mBitmapHeight;private float mDrawableRadius;private float mBorderRadius;private ColorFilter mColorFilter;private boolean mReady;private boolean mSetupPending;private boolean mBorderOverlay;private boolean mDisableCircularTransformation;public CircleImageView(Context context) {super(context);init();}public CircleImageView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public CircleImageView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircleImageView, defStyle, 0);mBorderWidth = a.getDimensionPixelSize(R.styleable.CircleImageView_civ_border_width, DEFAULT_BORDER_WIDTH);mBorderColor = a.getColor(R.styleable.CircleImageView_civ_border_color, DEFAULT_BORDER_COLOR);mBorderOverlay = a.getBoolean(R.styleable.CircleImageView_civ_border_overlay, DEFAULT_BORDER_OVERLAY);mFillColor = a.getColor(R.styleable.CircleImageView_civ_fill_color, DEFAULT_FILL_COLOR);a.recycle();init();}private void init() {super.setScaleType(SCALE_TYPE);mReady = true;if (mSetupPending) {setup();mSetupPending = false;}}@Overridepublic ScaleType getScaleType() {return SCALE_TYPE;}@Overridepublic void setScaleType(ScaleType scaleType) {if (scaleType != SCALE_TYPE) {throw new IllegalArgumentException(String.format("ScaleType %s not supported.", scaleType));}}@Overridepublic void setAdjustViewBounds(boolean adjustViewBounds) {if (adjustViewBounds) {throw new IllegalArgumentException("adjustViewBounds not supported.");}}@Overrideprotected void onDraw(Canvas canvas) {if (mDisableCircularTransformation) {super.onDraw(canvas);return;}if (mBitmap == null) {return;}if (mFillColor != Color.TRANSPARENT) {canvas.drawCircle(mDrawableRect.centerX(), mDrawableRect.centerY(), mDrawableRadius, mFillPaint);}canvas.drawCircle(mDrawableRect.centerX(), mDrawableRect.centerY(), mDrawableRadius, mBitmapPaint);if (mBorderWidth > 0) {canvas.drawCircle(mBorderRect.centerX(), mBorderRect.centerY(), mBorderRadius, mBorderPaint);}}@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);setup();}@Overridepublic void setPadding(int left, int top, int right, int bottom) {super.setPadding(left, top, right, bottom);setup();}@Overridepublic void setPaddingRelative(int start, int top, int end, int bottom) {super.setPaddingRelative(start, top, end, bottom);setup();}public int getBorderColor() {return mBorderColor;}public void setBorderColor(@ColorInt int borderColor) {if (borderColor == mBorderColor) {return;}mBorderColor = borderColor;mBorderPaint.setColor(mBorderColor);invalidate();}/*** @deprecated Use {@link #setBorderColor(int)} instead*/@Deprecatedpublic void setBorderColorResource(@ColorRes int borderColorRes) {setBorderColor(getContext().getResources().getColor(borderColorRes));}/*** Return the color drawn behind the circle-shaped drawable.** @return The color drawn behind the drawable** @deprecated Fill color support is going to be removed in the future*/@Deprecatedpublic int getFillColor() {return mFillColor;}/*** Set a color to be drawn behind the circle-shaped drawable. Note that* this has no effect if the drawable is opaque or no drawable is set.** @param fillColor The color to be drawn behind the drawable** @deprecated Fill color support is going to be removed in the future*/@Deprecatedpublic void setFillColor(@ColorInt int fillColor) {if (fillColor == mFillColor) {return;}mFillColor = fillColor;mFillPaint.setColor(fillColor);invalidate();}/*** Set a color to be drawn behind the circle-shaped drawable. Note that* this has no effect if the drawable is opaque or no drawable is set.** @param fillColorRes The color resource to be resolved to a color and*                     drawn behind the drawable** @deprecated Fill color support is going to be removed in the future*/@Deprecatedpublic void setFillColorResource(@ColorRes int fillColorRes) {setFillColor(getContext().getResources().getColor(fillColorRes));}public int getBorderWidth() {return mBorderWidth;}public void setBorderWidth(int borderWidth) {if (borderWidth == mBorderWidth) {return;}mBorderWidth = borderWidth;setup();}public boolean isBorderOverlay() {return mBorderOverlay;}public void setBorderOverlay(boolean borderOverlay) {if (borderOverlay == mBorderOverlay) {return;}mBorderOverlay = borderOverlay;setup();}public boolean isDisableCircularTransformation() {return mDisableCircularTransformation;}public void setDisableCircularTransformation(boolean disableCircularTransformation) {if (mDisableCircularTransformation == disableCircularTransformation) {return;}mDisableCircularTransformation = disableCircularTransformation;initializeBitmap();}@Overridepublic void setImageBitmap(Bitmap bm) {super.setImageBitmap(bm);initializeBitmap();}@Overridepublic void setImageDrawable(Drawable drawable) {super.setImageDrawable(drawable);initializeBitmap();}@Overridepublic void setImageResource(@DrawableRes int resId) {super.setImageResource(resId);initializeBitmap();}@Overridepublic void setImageURI(Uri uri) {super.setImageURI(uri);initializeBitmap();}@Overridepublic void setColorFilter(ColorFilter cf) {if (cf == mColorFilter) {return;}mColorFilter = cf;applyColorFilter();invalidate();}@Overridepublic ColorFilter getColorFilter() {return mColorFilter;}private void applyColorFilter() {if (mBitmapPaint != null) {mBitmapPaint.setColorFilter(mColorFilter);}}private Bitmap getBitmapFromDrawable(Drawable drawable) {if (drawable == null) {return null;}if (drawable instanceof BitmapDrawable) {return ((BitmapDrawable) drawable).getBitmap();}try {Bitmap bitmap;if (drawable instanceof ColorDrawable) {bitmap = Bitmap.createBitmap(COLORDRAWABLE_DIMENSION, COLORDRAWABLE_DIMENSION, BITMAP_CONFIG);} else {bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), BITMAP_CONFIG);}Canvas canvas = new Canvas(bitmap);drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());drawable.draw(canvas);return bitmap;} catch (Exception e) {e.printStackTrace();return null;}}private void initializeBitmap() {if (mDisableCircularTransformation) {mBitmap = null;} else {mBitmap = getBitmapFromDrawable(getDrawable());}setup();}private void setup() {if (!mReady) {mSetupPending = true;return;}if (getWidth() == 0 && getHeight() == 0) {return;}if (mBitmap == null) {invalidate();return;}mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);mBitmapPaint.setAntiAlias(true);mBitmapPaint.setShader(mBitmapShader);mBorderPaint.setStyle(Paint.Style.STROKE);mBorderPaint.setAntiAlias(true);mBorderPaint.setColor(mBorderColor);mBorderPaint.setStrokeWidth(mBorderWidth);mFillPaint.setStyle(Paint.Style.FILL);mFillPaint.setAntiAlias(true);mFillPaint.setColor(mFillColor);mBitmapHeight = mBitmap.getHeight();mBitmapWidth = mBitmap.getWidth();mBorderRect.set(calculateBounds());mBorderRadius = Math.min((mBorderRect.height() - mBorderWidth) / 2.0f, (mBorderRect.width() - mBorderWidth) / 2.0f);mDrawableRect.set(mBorderRect);if (!mBorderOverlay && mBorderWidth > 0) {mDrawableRect.inset(mBorderWidth - 1.0f, mBorderWidth - 1.0f);}mDrawableRadius = Math.min(mDrawableRect.height() / 2.0f, mDrawableRect.width() / 2.0f);applyColorFilter();updateShaderMatrix();invalidate();}private RectF calculateBounds() {int availableWidth  = getWidth() - getPaddingLeft() - getPaddingRight();int availableHeight = getHeight() - getPaddingTop() - getPaddingBottom();int sideLength = Math.min(availableWidth, availableHeight);float left = getPaddingLeft() + (availableWidth - sideLength) / 2f;float top = getPaddingTop() + (availableHeight - sideLength) / 2f;return new RectF(left, top, left + sideLength, top + sideLength);}private void updateShaderMatrix() {float scale;float dx = 0;float dy = 0;mShaderMatrix.set(null);if (mBitmapWidth * mDrawableRect.height() > mDrawableRect.width() * mBitmapHeight) {scale = mDrawableRect.height() / (float) mBitmapHeight;dx = (mDrawableRect.width() - mBitmapWidth * scale) * 0.5f;} else {scale = mDrawableRect.width() / (float) mBitmapWidth;dy = (mDrawableRect.height() - mBitmapHeight * scale) * 0.5f;}mShaderMatrix.setScale(scale, scale);mShaderMatrix.postTranslate((int) (dx + 0.5f) + mDrawableRect.left, (int) (dy + 0.5f) + mDrawableRect.top);mBitmapShader.setLocalMatrix(mShaderMatrix);}}

2.在res/value下新建att.xml(内容如下)

<?xml version="1.0" encoding="utf-8"?>
<resources><declare-styleable name="CircleImageView"><attr name="civ_border_width" format="dimension" /><attr name="civ_border_color" format="color" /><attr name="civ_border_overlay" format="boolean" /><attr name="civ_fill_color" format="color" /></declare-styleable>
</resources>

然后使用就和普通控件一样:

<com.example.myapplication.CircleImageViewandroid:layout_width="160dp"android:layout_height="160dp"android:layout_centerInParent="true"android:src="@drawable/head"app:civ_border_width="2dp"app:civ_border_color="@color/colorAccent"tools:ignore="MissingConstraints" />

初始使用用法,更多设置做完开发再补上;

代码很多参考了很多大佬的写法,再次不一一列出,侵删

安卓圆形图片控件CircleImageView的使用相关推荐

  1. MFC 对话框Picture Control(图片控件)中静态和动态显示Bmp图片

    最近有同学问我如何实现MFC基于对话框在图片控件中加载图片?其实使用MFC显示图片的方法各种各样,但是还是有些同学不知道怎样显示.以前在<数字图像处理>课程中完成的软件都是基于单文档的程序 ...

  2. Duilib实现圆形头像控件

    .h文件 1 #ifndef __UIHEADICON_H__ 2 #define __UIHEADICON_H__ 3 4 5 /* 6 名称:圆形头像控件(派生CButtonUI类) 7 */ 8 ...

  3. Android_安卓为按钮控件绑定事件的五种方式

    写在最前面 本次,来介绍一下安卓中为控件--Button绑定事件的五种方式. 二.具体的实现 第一种:直接绑定在Button控件上: 步骤1.在Button控件上设置android:onClick=& ...

  4. 工控软件图形界面-控件实现(圆形仪表控件三)(zz)

    介绍 在工业控制系统开发过程中,图形显示方面占有着很重要的作用.比起很多专用的组态软件,他们有着强大的在图形系统,能够组态出来非常漂亮的系统.现在的很多的工业图形开发包都需要支付费用,很多漂亮的控件比 ...

  5. VS2013 MFC 直接将 OpenCV2.0/3.0 库中的 Mat 结构的图像传递到 Picture Control(图片控件)

    接上文 VS2013 MFC + OpenCV3.0 打开图片: 既然我们已经从 OpenCV1.0 走到了 OpenCV2.0 乃至更高,又何苦在写基于 MFC 的图像处理程序时,又回到 OpenC ...

  6. 一步步学习微软InfoPath2010和SP2010--第十二章节--管理和监控InfoPath Form Services(IPFS)(4)--监控含图片控件的Products表单...

    如本章节前面提到的,你的IPFS表单表现没有你想象的好有很多可能的原因.一个最明显的原因是表单产生太多通信量(因为表单产生的HTML的大小).在许多你使用了大型.笨拙表单的许多方法中,最常见的是让用户 ...

  7. Android图片控件,跟随列表(recyclerView)的上下滚动而同步平移。

    一个用于放置在RecycleView中的图片控件,其主要功能是跟随列表的上下滚动而上下平移,使得呈现出一种图像相对列表静止的感觉. Overview ScrollingImageView 提供以下特性 ...

  8. 【Android之SmartImageView图片控件】

    源码地址是https://github.com/loopj/android-smart-image-view,没有sample,本文最后会提供一个sample. smartimageview提供的主要 ...

  9. android如何绑定事件,Android_安卓为按钮控件绑定事件的五种方式

    一.写在最前面 本次,来介绍一下安卓中为控件--Button绑定事件的五种方式. 二.具体的实现 第一种:直接绑定在Button控件上: 步骤1.在Button控件上设置android:onClick ...

最新文章

  1. R语言应用实战系列(四)-Apriori算法的相关内容(附案例源代码)
  2. 两难!到底用 Spring BeanUtils 还是 Apache BeanUtils?
  3. 端到端测试实践:Jenkins集成TestCafe
  4. 解决the resource is not on the build path of a java project
  5. TensorFlow多层感知机实现MINIST分类
  6. 终于有人说清楚了!内卷和努力到底有啥区别?
  7. 语言运算顺序题目_我的Python学习笔记:今天我学了关于Python里的运算符及运算顺序...
  8. KuaiRec | 快手发布首个稠密度高达99%的推荐数据集, 可用于多种推荐系统方向研究...
  9. 「职业生涯规划」真的有必要做吗?
  10. ARM指令学习,王明学learn
  11. 标准计算机教室方案,标准级多媒体网络教室方案
  12. 物联网芯片的协议之Lora及其调制
  13. c语言表达式优先级最高的是,C语言运算符优先级表
  14. 安卓使用教程:(八门神器)破解游戏内购方法及原理
  15. ubuntu20.04安装burpsuite
  16. 帝国cms如何安装php模板,帝国CMS整站源码通用安装教程
  17. 判断给出的秒数是几天几小时几分几秒
  18. TCP/IP_UDP归纳
  19. [附源码]java毕业设计房屋中介管理系统
  20. 软考高级-系统架构师-企业信息化战略与实施

热门文章

  1. INI文件解析、遍历
  2. 第29课:AD中class,设计参数,规则的设置
  3. 通过RSRP和SINR判断LTE信号质量
  4. 【中亦安图】清算/报表/日终跑批程序之性能优化案例(5)
  5. 60种生活小窍门,分享
  6. 2019.3.9 提高B组 T1 JZOJ 4742 单峰
  7. 『全闪实测』数据库加速解决方案
  8. 【OI做题记录】【BZOJ】【Usaco2008 Mar】土地购买
  9. JS高级程序设计读书笔记(第五章 引用变量)
  10. 深富策略军工股掀起涨停潮