Android(安卓)— 自定义圆形 ImageView 控件
16lz
2021-01-24
需求描述
越来越多的社交软件通过圆形外框来展现用户头像,因此我们需要将方形源文件以圆形来展示。
实现 src 圆形化显示
完整代码:
public class CircleImageView extends ImageView { private static final String TAG = "CircleImageView"; private Shader mShader; private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); public CircleImageView(Context context) { super(context); } @Override protected void onDraw(Canvas canvas) { Bitmap rawBitmap = getBitmap(getDrawable()); if (rawBitmap != null) { int viewWidth = getWidth(); int viewHeight = getHeight(); int viewMinSize = Math.min(viewWidth, viewHeight); if (mShader == null) { mShader = new BitmapShader(rawBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); } mPaint.setShader(mShader); float radius = viewMinSize / 2.0f; canvas.drawCircle(radius, radius, radius, mPaint); } else { super.onDraw(canvas); } } private Bitmap getBitmap(Drawable drawable) { if (drawable instanceof BitmapDrawable) { return ((BitmapDrawable) drawable).getBitmap(); } else if (drawable instanceof ColorDrawable) { Rect rect = drawable.getBounds(); int width = rect.width(); int height = rect.height(); int color = ((ColorDrawable) drawable).getColor(); Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); canvas.drawARGB(Color.alpha(color), Color.red(color), Color.green(color), Color.blue(color)); return bitmap; } else { return null; } }}
onDraw() 方法部分注释:
protected void onDraw(Canvas canvas) { // 通过 getBitMap 方法获取到原始 Bitmap Bitmap rawBitmap = getBitmap(getDrawable()); // Drawable 是 Bitmap 或 Color if (rawBitmap != null) { int viewWidth = getWidth(); int viewHeight = getHeight(); // 由于是圆形,所以需要两者中的 Min。 int viewMinSize = Math.min(viewWidth, viewHeight); // 判断 Shader 是否已经初始化过,避免绘制过程卡顿。 if (mShader == null) { // 把原始 Bitmap 给 Shader,模式为拉伸。 mShader = new BitmapShader(rawBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); } mPaint.setShader(mShader); // 得到圆形半径 float radius = viewMinSize / 2.0f; // 确定绘制 Circle 的中心点、半径和 Paint canvas.drawCircle(radius, radius, radius, mPaint); } else { super.onDraw(canvas); } }
getBitmap() 方法部分注释:
private Bitmap getBitmap(Drawable drawable) { // 如果是 Bitmap 类的 Drawable if (drawable instanceof BitmapDrawable) { return ((BitmapDrawable) drawable).getBitmap(); } else if (drawable instanceof ColorDrawable) { Rect rect = drawable.getBounds(); int width = rect.width(); int height = rect.height(); int color = ((ColorDrawable) drawable).getColor(); // 创建 ARGB_8888 格式的 Bitmap Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); // 绘制目标颜色,从而把颜色转换为 Bitmap canvas.drawARGB(Color.alpha(color), Color.red(color), Color.green(color), Color.blue(color)); return bitmap; } else { return null; } }
存在的问题:
对图片资源不会自动缩放,如果是用户自行上传的图片则可能造成资源浪费或者 OOM,但本次需求是系统自带的图标圆形化,所以不需要实现。如果需要实现则可以用 Matrix 实现,可以见文末参考处;
如果需要加上背景,那么 Background 依然是方形的,而不是圆形。
references:
http://www.cnblogs.com/goagen...
http://www.jianshu.com/p/ed5d...
更多相关文章
- android自由改变Dialog窗口位置的方法
- Android(安卓)JUnit单元测试基础实例
- android中保存Bitmap图片到指定文件夹中的方法
- 面试篇--android下网络通讯机制(三种网络通讯方式)
- Android(安卓)N NotificationManagerService源码分析
- SystemClock.sleep和Thread.sleep源码分析
- Android使用Jsoup解析Html表格的方法
- Android(安卓)Studio Gradle 重命名输出App或者Library的文件名
- Android(安卓)intent传递hashMap对象,遍历hashMap,改变menu状态