圆形的View(OutLineProvider)
view有一个outlineProvider,通过重写ViewOutlineProvider修改,设置一个radius属性,但是View必须是正方形,否则无法构成正圆形,需要注意的是view的outline
public class CircleFrameLayout extends FrameLayout {
/**
* 圆形的半径
*/
private int radius;
public CircleFrameLayout(Context context) {
this(context, null);
}
public CircleFrameLayout(Context context, AttributeSet attrs) {
super(context, attrs);
/**
* ViewOutlineProvider 在view的尺寸,padding,margin发生变化后会调用
*/
setOutlineProvider(new ViewOutlineProvider() {
@Override
public void getOutline(View view, Outline outline) {
Rect rect = new Rect(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
outline.setRoundRect(rect, radius);
}
});
setClipToOutline(true);
}
public void setRadius(int radius) {
this.radius = radius;
invalidateOutline();
}
}
圆形的View(通过重新onDraw方法)
实现一个圆形头像图片的显示
/**
* 圆形的图片,用于显示头像等
*/
public class RoundImageView extends AppCompatImageView {
private Bitmap mBitmap;
private Rect mRect = new Rect();
private PaintFlagsDrawFilter pdf = new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG);
private Paint mPaint = new Paint();
private Path mPath = new Path();
public RoundImageView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
//传入一个Bitmap对象
public void setBitmap(Bitmap bitmap) {
this.mBitmap = bitmap;
}
private void init() {
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
mPaint.setAntiAlias(true);// 抗锯尺
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mBitmap == null) {
return;
}
mRect.set(0, 0, getWidth(), getHeight());
canvas.save();
canvas.setDrawFilter(pdf);
mPath.addCircle(getWidth() / 2, getWidth() / 2, getHeight() / 2, Path.Direction.CCW);
canvas.clipPath(mPath);
canvas.drawBitmap(mBitmap, null, mRect, mPaint);
canvas.restore();
}
}
SurfaceView圆形预览框
- 注意点:需要重新的draw方法而非OnDraw方法,需要调用setWillNotDraw(false)
/**
* 定义一个圆形的SurfaceView
*/
public class CircleSurfaceView extends SurfaceView {
/**
* 圆心位置
*/
private Point mOrigin = new Point(0, 0);
/**
* 圆形半径
*/
private int mRadius;
public CircleSurfaceView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public CircleSurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public CircleSurfaceView(Context context) {
super(context);
init();
}
private void init() {
this.setFocusable(true);
this.setFocusableInTouchMode(true);
this.setWillNotDraw(false);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int n = Math.min(MeasureSpec.getSize(widthMeasureSpec),
MeasureSpec.getSize(heightMeasureSpec));
mOrigin = new Point(n / 2, n / 2);
mRadius = n / 2;
}
@Override
public void draw(Canvas canvas) {
Path path = new Path();
path.addCircle(mOrigin.x, mOrigin.y, mRadius, Path.Direction.CCW);
canvas.clipPath(path, Region.Op.INTERSECT);
super.draw(canvas);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
}
}