美文网首页
Android自定义圆形View

Android自定义圆形View

作者: 富多多 | 来源:发表于2020-04-23 23:25 被阅读0次

圆形的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);
    }
}

相关文章

网友评论

      本文标题:Android自定义圆形View

      本文链接:https://www.haomeiwen.com/subject/qndtwhtx.html