以前不论是圆角图片还是圆形图片,一般都是通过重新创建一个对应形状的Bitmap,然后重新设置。现在找到了一个好的方法,就是利用Xfermode的图片渲染合成原理,然后使用Path构造我们需要的效果范围,在onDraw的时候,将范围外的所有部分过滤掉。看效果图:
其实实现原理非常简单,并且可以无限扩展。
<pre name="code" class="java">public abstract class Shaper {
private Paint mPaint;
private Path mPath;
public Shaper(View view) {
view.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setColor(Color.TRANSPARENT);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
mPath = new Path();
}
protected abstract boolean isSquare();
protected abstract void onShape(float left, float top, float right, float bottom, Path path);
public void shape(Canvas canvas) {
float left = 0, top = 0, right = canvas.getWidth(), bottom = canvas.getHeight();
if (isSquare() && canvas.getWidth() != canvas.getHeight()) {
if (canvas.getWidth() > canvas.getHeight()) {
float d = canvas.getWidth() - canvas.getHeight();
left = d / 2;
right = canvas.getWidth() - d / 2;
} else {
float d = canvas.getHeight() - canvas.getWidth();
top = d / 2;
bottom = canvas.getHeight() - d / 2;
}
}
mPath.reset();
onShape(left, top, right, bottom, mPath);
mPath.setFillType(FillType.INVERSE_EVEN_ODD);
canvas.drawPath(mPath, mPaint);
}
public void setBlankColor(int color) {
mPaint.setColor(color);
}
}
下面是圆角矩形的实现:
public class RoundRectShaper extends Shaper {
private float radius;
public RoundRectShaper(View view, float radius) {
super(view);
this.radius = radius;
}
@Override
public boolean isSquare() {
return false;
}
@Override
public void onShape(float left, float top, float right, float bottom,
Path path) {
float width = right - left;
float height = bottom - top;
path.addRoundRect(new RectF(0, 0, width, height), radius, radius,
Direction.CCW);
}
}
使用方式:
public class ShaperImageView extends ImageView {
private Shaper mShaper;
public ShaperImageView(Context context) {
super(context);
}
public ShaperImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mShaper != null) {
mShaper.shape(canvas);
}
}
public void setShaper(Shaper shaper) {
mShaper = shaper;
}
}
OK,so easy!
源码:https://github.com/PoetKing/Shaper