public class CircleImageView extends ImageView { 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 = 1; private static final int DEFAULT_BORDER_WIDTH = 0; private static final int DEFAULT_BORDER_COLOR = 0; 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 int mBorderColor = DEFAULT_BORDER_COLOR; private int mBorderWidth = DEFAULT_BORDER_WIDTH; private Bitmap mBitmap; private BitmapShader mBitmapShader; private int mBitmapWidth; private int mBitmapHeight; private float mDrawableRadius; private float mBorderRadius; private boolean mReady; private boolean mSetupPending; public CircleImageView(Context context) { super(context); } public CircleImageView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public CircleImageView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); super.setScaleType(SCALE_TYPE); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircleImageView, defStyle, 0); mBorderWidth = a.getDimensionPixelSize(R.styleable.CircleImageView_border_width, DEFAULT_BORDER_WIDTH); mBorderColor = a.getColor(R.styleable.CircleImageView_border_color, DEFAULT_BORDER_COLOR); a.recycle(); mReady = true; if (mSetupPending) { setup(); mSetupPending = false; } } @Override public ScaleType getScaleType() { return SCALE_TYPE; } @Override public void setScaleType(ScaleType scaleType) { if (scaleType != SCALE_TYPE) { throw new IllegalArgumentException(String.format("ScaleType %s not supported.", scaleType)); } } @Override protected void onDraw(Canvas canvas) { if (getDrawable() == null) { return; } canvas.drawCircle(getWidth() / 2, getHeight() / 2, mDrawableRadius, mBitmapPaint); canvas.drawCircle(getWidth() / 2, getHeight() / 2, mBorderRadius, mBorderPaint); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); setup(); } public int getBorderColor() { return mBorderColor; } public void setBorderColor(int borderColor) { if (borderColor == mBorderColor) { return; } mBorderColor = borderColor; mBorderPaint.setColor(mBorderColor); invalidate(); } public int getBorderWidth() { return mBorderWidth; } public void setBorderWidth(int borderWidth) { if (borderWidth == mBorderWidth) { return; } mBorderWidth = borderWidth; setup(); } @Override public void setImageBitmap(Bitmap bm) { super.setImageBitmap(bm); mBitmap = bm; setup(); } @Override public void setImageDrawable(Drawable drawable) { super.setImageDrawable(drawable); mBitmap = getBitmapFromDrawable(drawable); setup(); } @Override public void setImageResource(int resId) { super.setImageResource(resId); mBitmap = getBitmapFromDrawable(getDrawable()); setup(); } 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 (OutOfMemoryError e) { return null; } } private void setup() { if (!mReady) { mSetupPending = true; return; } if (mBitmap == null) { 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); mBitmapHeight = mBitmap.getHeight(); mBitmapWidth = mBitmap.getWidth(); mBorderRect.set(0, 0, getWidth(), getHeight()); mBorderRadius = Math.min((mBorderRect.height() - mBorderWidth) / 2, (mBorderRect.width() - mBorderWidth) / 2); mDrawableRect.set(mBorderWidth, mBorderWidth, mBorderRect.width() - mBorderWidth, mBorderRect.height() - mBorderWidth); mDrawableRadius = Math.min(mDrawableRect.height() / 2, mDrawableRect.width() / 2); updateShaderMatrix(); invalidate(); } 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) + mBorderWidth, (int) (dy + 0.5f) + mBorderWidth); mBitmapShader.setLocalMatrix(mShaderMatrix); } } //////属性attr.xml <declare-styleable name="CircleImageView"> <attr name="border_width" format="dimension" /> <attr name="border_color" format="color" /> </declare-styleable>
相关推荐
"34个圆形图标"这个资源集合提供了一系列具有圆形边框的图标,这些图标可能被广泛应用于各种数字产品,如手机应用、网站、游戏、软件和其他交互式平台。以下是关于圆形图标及其相关知识点的详细说明: 1. 圆形图标...
在IT行业中,设计一个美观且用户友好的界面是至关重要的,尤其在移动设备和平板电脑上,圆形图标菜单因其独特的视觉效果和易于操作性而受到欢迎。标题"圆形图标菜单中间大圆形周围子圆形.zip"暗示了我们正在讨论一种...
在Android或iOS等移动应用开发中,自定义圆形图标,如圆形头像,是一个常见的需求。这涉及到图像处理和UI设计的技术,特别是在个人资料、社交应用或者任何需要展示用户形象的地方。本文将深入探讨如何在Android和iOS...
"可以制作圆形图标"这一特点意味着这个工具可能提供了自定义形状的功能,允许用户创建具有圆形裁剪的图标。圆形图标在现代设计趋势中颇为流行,因为它们通常给人一种简洁、专业的印象,尤其适用于移动应用和品牌标识...
这个场景中,我们讨论的是如何手工绘制一个带有三层渐变色的圆形图标。这个过程涉及到对Android图形绘制的理解,特别是使用`LayerDrawable`和颜色渐变的概念。 首先,我们要明白`LayerDrawable`是Android中的一个...
"PPT商务按钮圆形图标下载.rar"是一个压缩包文件,它包含了一系列适用于商务PPT的圆形图标,旨在提升演示文稿的专业性和视觉吸引力。这些图标包括沙漏、咖啡杯、手型、曲别针、对号、眼睛、音符、复制图案、剪刀和...
"icon圆形图标自动生成工具"正是为了满足这一需求而诞生的工具,它能帮助设计师或开发者快速创建出专业且一致的圆形图标,并带有左上角的亮点效果,提升整体应用的视觉吸引力。 该工具的核心功能在于自动化生成过程...
"117张PNG格式圆形图标素材"是一份极具价值的资源集合,对于从事美工设计、网页制作的专业人士或是业余爱好者来说,这样的图标库是提高工作效率和作品质量的重要工具。 PNG是一种无损压缩的图像文件格式,其透明度...
在本文中,我们将深入探讨如何使用CSS3技术创建一个位于页面右下角的悬浮圆形图标,该图标可以作为客服菜单,包含如展开二维码、QQ客服等功能。CSS3是层叠样式表(Cascading Style Sheets)的第三个版本,它引入了...
【OC-Catalina主题(圆形图标).zip】是一个针对操作系统进行个性化定制的主题包,尤其适用于那些使用Openbox窗口管理器或类似环境的用户。"OC"可能代表"Openbox Config"或者"Original Creation",暗示这个主题是为...
在本文中,我们将深入探讨如何使用jQuery和CSS3创建一个具有圆形图标菜单的旋转切换效果。这个设计元素常用于网站导航,提供一种吸引用户注意力并交互的方式。让我们逐一解析实现这个功能所需的关键技术和步骤。 ...
在这个案例中,“js+css3交互式圆形图标菜单导航代码”就是一个很好的示例,它利用JavaScript和CSS3的强大功能,为用户提供了直观且有趣的菜单导航体验。下面将详细介绍这个项目中的核心技术和实现方式。 首先,...
"圆形图标插件"则为设计师提供了便捷的工具,它可能包含预设的圆形模板、形状工具、颜色库和导出选项等功能,帮助设计师快速创建专业且一致的圆形图标。使用这样的插件,设计师可以节省时间,专注于创新和细节优化,...
《CSS3右下角悬浮圆形图标客服菜单代码详解》 在网页设计中,为了提供更好的用户体验,常常会采用一些互动性较强的元素,如悬浮图标、菜单等。本篇将详细解析一个利用CSS3实现的右下角悬浮圆形图标,点击后展开客服...
【jQuery圆形图标菜单旋转切换代码】是一个利用JavaScript库jQuery和CSS3技术实现的创新性菜单导航解决方案。这个特效设计独特,以圆形布局展示图标菜单,并通过动态旋转来切换不同的选项,为用户提供了新颖且交互性...
本图标库为多彩扁平圆形图标元件库,以彩色镂空设计为主,适用于设置项、菜单栏、导航栏等模块的原型设计,可应用于休闲类、可爱类、轻商务类、游戏类的APP或网站。 本图标库的所有图标均为矢量格式,是由SVG转换而...
《JS+CSS3交互式圆形图标菜单导航代码详解》 在网页设计中,交互式的菜单导航是提升用户体验的重要元素之一。本资源“js+css3交互式圆形图标菜单导航代码.zip”提供了一种创新的解决方案,它巧妙地结合了JavaScript...
【jQuery圆形图标菜单旋转切换代码】是一个基于jQuery和CSS实现的网页交互效果,它通过将图标设置为圆形并实现旋转切换,为用户界面增添了一种动态且吸引人的元素。这个特效代码非常适合用于网站导航菜单或者按钮...
在本文中,我们将深入探讨如何使用jQuery来创建一个具有圆形图标菜单并实现旋转切换效果的交互式用户界面。jQuery是一个广泛使用的JavaScript库,它简化了DOM操作、事件处理和动画制作,使得创建复杂的网页交互变得...
在本文中,我们将深入探讨如何实现"jQuery+CSS3可拖拽气泡圆形图标菜单特效"这一创新的网页设计技术。这种特效为用户提供了一种独特的交互体验,通过鼠标拖动来切换菜单项,并且在点击图标后能弹出子菜单。下面我们...