RoundImageView是在不修改ImageView原有绘图逻辑的情况下实现的圆形特性,完全兼容ImageView的所有特性。
无论你的图像控件布局是什么样的,图像内容是什么样的,RoundImageView不圆不是英雄!
无论你的图像控件ScaleType是什么样的,矩阵转换MATRIX是什么样的,RoundImageView不圆不是传说!
无论你的控件或图像经过何种变换,比如内边距偏移,缩放,居中等等,你会发现一个圆紧紧的跟随着你的控件或图片,不离不弃,这就是神话级的圆形控件RoundImageView!
RoundImageView的使用非常简单,无需任何额外依赖和xml属性配置,让哪些动辄就弄几个xml属性的都消失!
以下是几个常用属性设置接口:
1、setRoundMode:设置圆形模式。RoundImageView支持两种圆形模式:
(1)圆形视图:ROUND_VIEW, 使视图组件变圆;
(2)圆形图片:ROUND_DRAWABLE,使图片内容变圆。
2、setBorderColor:设置圆环颜色,默认为透明色;
3、setBorderWidth:设置圆环宽度,默认为0。如果圆环宽度小于等于0,圆环不会被绘制;
4、setFillColor:设置圆形区域填充背景色,默认为透明色。
源代码如下:
package com.example.roundimageview;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.PorterDuff.Mode;
import android.os.Build;
import android.util.AttributeSet;
import android.widget.ImageView;
public class RoundImageView extends ImageView {
public enum RoundMode {
ROUND_VIEW, ROUND_DRAWABLE
}
private static final int DEFAULT_BORDER_WIDTH = 0;
private static final int DEFAULT_BORDER_COLOR = Color.TRANSPARENT;
private static final int DEFAULT_FILL_COLOR = Color.TRANSPARENT;
private boolean roundDisable;
private RoundMode roundMode = RoundMode.ROUND_DRAWABLE;
private int borderColor = DEFAULT_BORDER_COLOR;
private int borderWidth = DEFAULT_BORDER_WIDTH;
private int fillColor = DEFAULT_FILL_COLOR;
private Paint borderPaint;
private Paint fillPaint;
private Paint imagePaint;
private Paint portPaint;
private Rect bounds = new Rect();
private float radius = 0;
private float cx = 0;
private float cy = 0;
public RoundImageView(Context context) {
super(context);
initView();
}
public RoundImageView(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
}
public RoundImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView();
}
private void initView() {
portPaint = new Paint();
portPaint.setAntiAlias(true);
borderPaint = new Paint();
borderPaint.setAntiAlias(true);
borderPaint.setColor(DEFAULT_BORDER_COLOR);
borderPaint.setStrokeWidth(DEFAULT_BORDER_WIDTH);
borderPaint.setStyle(Style.STROKE);
fillPaint = new Paint();
fillPaint.setAntiAlias(true);
fillPaint.setColor(DEFAULT_FILL_COLOR);
fillPaint.setStyle(Style.FILL);
imagePaint = new Paint();
imagePaint.setAntiAlias(true);
imagePaint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
}
public void setRoundMode(RoundMode roundMode) {
if (roundMode == null) {
throw new IllegalArgumentException("roundMode is null.");
}
if (this.roundMode != roundMode) {
this.roundMode = roundMode;
invalidate();
}
}
public void setRoundDisable(boolean roundDisable) {
if (this.roundDisable != roundDisable) {
this.roundDisable = roundDisable;
invalidate();
}
}
public boolean isRoundDisable() {
return roundDisable;
}
public void setBorderColor(int borderColor) {
if (this.borderColor != borderColor) {
this.borderColor = borderColor;
borderPaint.setColor(borderColor);
invalidate();
}
}
public void setBorderWidth(int borderWidth) {
if (this.borderWidth != borderWidth) {
this.borderWidth = borderWidth;
borderPaint.setStrokeWidth(borderWidth);
invalidate();
}
}
public void setFillColor(int fillColor) {
if (this.fillColor != fillColor) {
this.fillColor = fillColor;
fillPaint.setColor(fillColor);
invalidate();
}
}
@Override
protected void onDraw(Canvas canvas) {
if (roundDisable) {
super.onDraw(canvas);
return;
}
if (getDrawable() == null && roundMode == RoundMode.ROUND_DRAWABLE) {
super.onDraw(canvas);
return;
}
computeRoundBounds();
drawCircle(canvas);
drawImage(canvas);
}
private void drawImage(Canvas canvas) {
Bitmap src = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_4444);
super.onDraw(new Canvas(src));
Bitmap port = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_4444);
Canvas portCanvas = new Canvas(port);
int saveCount = portCanvas.getSaveCount();
portCanvas.save();
adjustCanvas(portCanvas);
portCanvas.drawCircle(cx, cy, radius, portPaint);
portCanvas.restoreToCount(saveCount);
portCanvas.drawBitmap(src, 0, 0, imagePaint);
src.recycle();
canvas.drawBitmap(port, 0, 0, null);
port.recycle();
}
private void drawCircle(Canvas canvas) {
int saveCount = canvas.getSaveCount();
canvas.save();
adjustCanvas(canvas);
canvas.drawCircle(cx, cy, radius, fillPaint);
if (borderWidth > 0) {
canvas.drawCircle(cx, cy, radius - borderWidth / 2f, borderPaint);
}
canvas.restoreToCount(saveCount);
}
private void computeRoundBounds() {
if (roundMode == RoundMode.ROUND_VIEW) {
bounds.left = getPaddingLeft();
bounds.top = getPaddingTop();
bounds.right = getWidth() - getPaddingRight();
bounds.bottom = getHeight() - getPaddingBottom();
} else if (roundMode == RoundMode.ROUND_DRAWABLE) {
getDrawable().copyBounds(bounds);
} else {
throw new RuntimeException("unknown round mode:" + roundMode);
}
radius = Math.min(bounds.width(), bounds.height()) / 2f;
cx = bounds.left + bounds.width() / 2f;
cy = bounds.top + bounds.height() / 2f;
}
private void adjustCanvas(Canvas canvas) {
if (roundMode == RoundMode.ROUND_DRAWABLE) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
if (getCropToPadding()) {
final int scrollX = getScrollX();
final int scrollY = getScrollY();
canvas.clipRect(scrollX + getPaddingLeft(), scrollY + getPaddingTop(),
scrollX + getRight() - getLeft() - getPaddingRight(),
scrollY + getBottom() - getTop() - getPaddingBottom());
}
}
canvas.translate(getPaddingLeft(), getPaddingTop());
if (getImageMatrix() != null) {
Matrix m = new Matrix(getImageMatrix());
canvas.concat(m);
}
}
}
}
1、默认使用
RoundImageView imageView=new RoundImageView(getApplicationContext());
imageView.setImageResource(R.drawable.m);
setContentView(imageView,new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
2、给组件加点偏移
RoundImageView imageView=new RoundImageView(getApplicationContext());
imageView.setPadding(200, 100, 20, 0);
imageView.setImageResource(R.drawable.m);
setContentView(imageView,new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
国际惯例
————————————————————————————————————————————————————————
作者:薄荷记账 (转载请注明原作者)
简洁 稳定 优雅 无限可能!