效果预览
本次的图片效果是基于上一篇博客的三种方法进行扩展实现图片的外边框效果。上一篇博客的传送门。
下面开始进行到整体,针对上次实现圆形图片的三个方式添加一个外边框效果。
使用PorterDuffXfermode方式来实现
我们使用这个方式实现圆形图片的原理是通过图片的设置图片的叠加显示效果。还是这张图:
思路
实现圆形图片,我们只需要绘制一个圆,并将模式设置为SRC_IN
即可。但是我们需要在外围添加一个边框的话,就不会那么简单了。我们需要绘制三次图片,通过合理的设置他们的Xfermode
模式来达到我们的要求。具体步骤为:
1. 将原图片绘制出来(如果有需要,进行必要的比例缩放处理,使其是一个正方形)
2. 绘制一个等大的正方形,颜色为边框要显示的颜色。(这一步的目的是为了将外围的边框也绘制出来)
3. 绘制一个半径为二分之一边长减去边框长度的圆,模式为DST_OUT
4. 绘制一个半径为二分之一边长的圆,模式为DST_IN
通过上面四步,基本就实现了我们想要的外边框的效果。
用图表示为:
具体细节可以参考代码实现。
代码
自定义viewCircleImageView1
的代码如下。
public class CircleImageView1 extends ImageView {
public static final int DEFAULT_BORDER_WIDTH = 0;
private Paint mPaint;
private Paint mBorderPaint;
private Shape mShape;
private Shape mBorderShape;
private float mRadius;
private float mBorderWidth;
private int mBorderColor;
private PorterDuffXfermode mBorderDuffMode;
private Bitmap mBorderBitmap;
private float[] outerRadii = new float[8];
public CircleImageView1(Context context) {
this(context, null);
}
public CircleImageView1(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public CircleImageView1(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView(attrs);
}
private void initView(AttributeSet attrs) {
if (attrs != null) {
TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.CircleImageView1);
mBorderWidth = a.getDimensionPixelSize(R.styleable.CircleImageView1_circle_border_width1, DEFAULT_BORDER_WIDTH);
mBorderColor = a.getInt(R.styleable.CircleImageView1_circle_border_color1, Color.BLACK);
a.recycle();
}
setLayerType(LAYER_TYPE_HARDWARE, null);
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setColor(Color.BLACK);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
if (mBorderWidth != DEFAULT_BORDER_WIDTH) {
mBorderPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mBorderPaint.setColor(mBorderColor);
mBorderPaint.setFilterBitmap(true);
mBorderDuffMode = new PorterDuffXfermode(PorterDuff.Mode.DST_OUT);
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = getMeasuredWidth();
int height = getMeasuredHeight();
int min = Math.min(width, height);
mRadius = min / 2;
setMeasuredDimension(min, min);
}