自定义Drawable绘图-圆形、正三角、梯形等

自定义Drawable,绘制圆形、正三角形、二阶贝塞尔曲线、梯形等。

圆形

        // 画圆
        PointF point = new PointF(radius, radius);
        canvas.drawCircle(point.x, point.y, radius, mPaint);

正三角

        // 画正三角
        PointF trianglePoint1 = new PointF(radius, radius*2);
        PointF trianglePoint2 = calculatePoint(trianglePoint1, radius*2, -60);
        PointF trianglePoint3 = calculatePoint(trianglePoint1, radius*2, -120);
        Path mPath = new Path();
        mPath.reset();
        mPath.moveTo(trianglePoint1.x, trianglePoint1.y);
        mPath.lineTo(trianglePoint2.x, trianglePoint2.y);
        mPath.lineTo(trianglePoint3.x, trianglePoint3.y);
        canvas.drawPath(mPath, mPaint);

梯形

        // 画梯形
        PointF trapezoidTopMiddlePoint = new PointF(radius*4, radius/2);
        PointF trapezoidPoint1 = calculatePoint(trapezoidTopMiddlePoint, radius/2, 0);
        PointF trapezoidPoint2 = calculatePoint(trapezoidTopMiddlePoint, radius/2, -180);
        PointF trapezoidBottomMiddlePoint = new PointF(radius*4, radius*1.6F);
        PointF trapezoidPoint3 = calculatePoint(trapezoidBottomMiddlePoint, radius, 0);
        PointF trapezoidPoint4 = calculatePoint(trapezoidBottomMiddlePoint, radius, -180);
        mPath.reset();
        mPath.moveTo(trapezoidPoint1.x, trapezoidPoint1.y);
        mPath.lineTo(trapezoidPoint2.x, trapezoidPoint2.y);
        mPath.lineTo(trapezoidPoint4.x, trapezoidPoint4.y);
        mPath.lineTo(trapezoidPoint3.x, trapezoidPoint3.y);
        canvas.drawPath(mPath, mPaint);

二阶贝塞尔曲线

        // 二阶贝塞尔曲线
        PointF bezierStartPoint = new PointF(radius*2, radius*2);
        PointF bezierEndPoint = new PointF(radius*4, radius*2);
        PointF controlPoint = new PointF(radius*6f, radius*6f);
        mPath.reset();
        mPath.moveTo(bezierStartPoint.x, bezierStartPoint.y);
        mPath.quadTo(controlPoint.x, controlPoint.y, bezierEndPoint.x, bezierEndPoint.y);
        canvas.drawPath(mPath, mPaint);

根据起点、角度、长度,计算终点位置

    public PointF calculatePoint(PointF point, float length, float angle){
        float x = (float) (Math.cos(Math.toRadians(angle)) * length);
        float y = (float) (Math.sin(Math.toRadians(angle-180)) * length);
        return new PointF(point.x+x, point.y + y);
    }

Math.toRadians:将角度转成弧度
在这里插入图片描述

效果图

在这里插入图片描述

自定义Drawable完整代码:GitHub

public class TestDrawable extends Drawable {

    private Paint mPaint;

    // 半径
    float radius = 200;

    public TestDrawable(){
        mPaint = new Paint();
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setAntiAlias(true);
        mPaint.setDither(true);
        mPaint.setARGB(100, 244, 92, 71);
    }

    @Override
    public void draw(@NonNull Canvas canvas) {

        // 画圆
        PointF point = new PointF(radius, radius);
        canvas.drawCircle(point.x, point.y, radius, mPaint);

        // 画正三角
        PointF trianglePoint1 = new PointF(radius, radius*2);
        PointF trianglePoint2 = calculatePoint(trianglePoint1, radius*2, -60);
        PointF trianglePoint3 = calculatePoint(trianglePoint1, radius*2, -120);
        Path mPath = new Path();
        mPath.reset();
        mPath.moveTo(trianglePoint1.x, trianglePoint1.y);
        mPath.lineTo(trianglePoint2.x, trianglePoint2.y);
        mPath.lineTo(trianglePoint3.x, trianglePoint3.y);
        canvas.drawPath(mPath, mPaint);

        // 画梯形
        PointF trapezoidTopMiddlePoint = new PointF(radius*4, radius/2);
        PointF trapezoidPoint1 = calculatePoint(trapezoidTopMiddlePoint, radius/2, 0);
        PointF trapezoidPoint2 = calculatePoint(trapezoidTopMiddlePoint, radius/2, -180);
        PointF trapezoidBottomMiddlePoint = new PointF(radius*4, radius*1.6F);
        PointF trapezoidPoint3 = calculatePoint(trapezoidBottomMiddlePoint, radius, 0);
        PointF trapezoidPoint4 = calculatePoint(trapezoidBottomMiddlePoint, radius, -180);
        mPath.reset();
        mPath.moveTo(trapezoidPoint1.x, trapezoidPoint1.y);
        mPath.lineTo(trapezoidPoint2.x, trapezoidPoint2.y);
        mPath.lineTo(trapezoidPoint4.x, trapezoidPoint4.y);
        mPath.lineTo(trapezoidPoint3.x, trapezoidPoint3.y);
        canvas.drawPath(mPath, mPaint);

        // 二阶贝塞尔曲线
        PointF bezierStartPoint = new PointF(radius*2, radius*2);
        PointF bezierEndPoint = new PointF(radius*4, radius*2);
        PointF controlPoint = new PointF(radius*6f, radius*6f);
        mPath.reset();
        mPath.moveTo(bezierStartPoint.x, bezierStartPoint.y);
        mPath.quadTo(controlPoint.x, controlPoint.y, bezierEndPoint.x, bezierEndPoint.y);
        canvas.drawPath(mPath, mPaint);

    }

    public PointF calculatePoint(PointF point, float length, float angle){
        float x = (float) (Math.cos(Math.toRadians(angle)) * length);
        float y = (float) (Math.sin(Math.toRadians(angle-180)) * length);
        return new PointF(point.x+x, point.y + y);
    }


    @Override
    public void setAlpha(int i) {
        mPaint.setAlpha(i);
    }

    @Override
    public void setColorFilter(@Nullable ColorFilter colorFilter) {
        mPaint.setColorFilter(colorFilter);
    }

    @Override
    public int getOpacity() {
        return PixelFormat.TRANSLUCENT;
    }

    @Override
    public int getIntrinsicHeight() {
//        return super.getIntrinsicHeight();
        return (int)(6 * radius);
    }


    @Override
    public int getIntrinsicWidth() {
        return super.getIntrinsicWidth();
    }
}

setAlpha

设置Drawable的透明度
setColor() 的助手,它只分配颜色的 alpha 值,保持其 r,g,b 值不变。 如果 alpha 值超出范围 [0…255],则结果未定义

setColorFilter

设置或清除paint的颜色过滤器,返回参数。

getOpacity

    @Override
    public int getOpacity() {
        return PixelFormat.TRANSLUCENT;
    }

可以根据setAlpha中设置的值进行调整
alpha 为0,设置PixelFormat.TRANSPARENT;
alpha 为255,设置PixelFormat.OPAQUE;
alpha为其它值,设置PixelFormat.TRANSLUCENT;

PixelFormat描述
OPAQUE完全不透明,覆盖它下面的所有内容
TRANSLUCENT完全透明,完全不显示任何东西
TRANSLUCENT只有绘制的地方,才会覆盖下面的内容

path

Path封装了由直线和曲线(二次,三次贝塞尔曲线)构成的几何路径。
注意:用drawPath绘制了后,Path的路径还是存在的,所以如果需要绘制新的路径,需要先调用Path的reset方法。

getIntrinsicHeight、getIntrinsicWidth

view使用了wrap_content时,设置固定的高度/宽度,默认为-1

练习绘制小鱼鱼

    源码地址:DrawableTest

    效果图:
在这里插入图片描述

日进一步!持续努力!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值