Paint绘制简单的进度条

paint也是画笔,可以再canvas上绘制任意的点、线、形、色等,熟练使用paint可以组装出很漂亮的自定义控件,下面用piant画了一个简单的加载进度
这里写图片描述

绘制的时候要注意文字的宽度和位置,而是使用paint的style,比如描边,填充等。

先看布局文件和attrs属性代码


<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="PaintProgress">
        <attr name="textSize" format="dimension" />
        <attr name="textColor" format="color" />
        <!--是否显示百分号-->
        <attr name="showPercent" format="boolean" />
        <!--进度条的颜色-->
        <attr name="roundColor" format="color" />
        <!--圆环的宽度-->
        <attr name="roundWidth" format="dimension" />
        <!--当前进度-->
        <attr name="progress" format="integer" />
        <!--内圆的半径-->
        <attr name="circleRadius" format="dimension" />
    </declare-styleable>
</resources>
  <com.example.administrator.meterialdesignpaintdemo.PaintProgress
        android:id="@+id/progressBar"
        android:layout_width="match_parent"
        android:layout_height="400dp"
        app:roundColor="@color/colorAccent"
        app:roundWidth="10dp"
        app:showPercent="true"
        app:textColor="@color/colorPrimary"
        app:circleRadius="60dp"
        app:textSize="40sp" />

接下来是控件的代码

public class PaintProgress extends View {

    final String TAG = "==test==";
    private final boolean showPercent;
    private final float roundWidth;
    private final int roundColor;
    private  int progress;
    private final Paint textPaint;
    private String drawnText = "";
    private int cX;
    private int cY;
    private final Paint arcPaint;
    private final Paint paint;
    private int circleRaidus;

    public PaintProgress(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.PaintProgress);
        showPercent = typedArray.getBoolean(R.styleable.PaintProgress_showPercent, true);
        roundWidth = typedArray.getDimension(R.styleable.PaintProgress_roundWidth, 6);
        roundColor = typedArray.getColor(R.styleable.PaintProgress_roundColor, Color.RED);
        progress = typedArray.getInteger(R.styleable.PaintProgress_progress, 0);
        float textSize = typedArray.getDimension(R.styleable.PaintProgress_textSize, 20);
        int textColor = typedArray.getColor(R.styleable.PaintProgress_textColor, Color.BLACK);
        circleRaidus= (int) typedArray.getDimension(R.styleable.PaintProgress_circleRadius,80);
        Log.i(TAG, "PaintProgress: ==" + textSize);
        typedArray.recycle();
        textPaint = new Paint();
        textPaint.setColor(textColor);
        textPaint.setTextSize(textSize);

        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(roundColor);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(roundWidth);

        arcPaint = new Paint();
        arcPaint.setStrokeWidth(roundWidth);
        arcPaint.setColor(Color.BLUE);
        arcPaint.setStyle(Paint.Style.STROKE);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //尺寸测量方面不考虑细致
        cX = MeasureSpec.getSize(widthMeasureSpec) / 2;
        cY = MeasureSpec.getSize(heightMeasureSpec) / 2;

        Log.i(TAG, "onMeasure: 测量结果=" + cX + " , " + cY);
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //首先画一个圆环
        Log.i(TAG, "onDraw: 开始绘制");
        canvas.drawCircle(cX, cY, circleRaidus+roundWidth, paint);
        //开始绘制中间文字
        if (showPercent) {
            drawnText = progress + "%";
        } else {
            drawnText = progress + "";
        }
        float textWidth = textPaint.measureText(drawnText);
        Paint.FontMetrics fontMetrics = textPaint.getFontMetrics();
        float ctY = (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom;
        canvas.drawText(drawnText, cX - textWidth / 2, ctY + cY, textPaint);
        //绘制转动圆弧
        /**
         * @param oval       园的矩形
         * @param startAngle 角度
         * @param sweepAngle 增加的角度
         * @param useCenter  是否填充绘制的整个扇形要注意和piant的sytle相互搭配
         * @param paint      The paint used to draw the arc
         */
        RectF oval = new RectF(cX -(circleRaidus+roundWidth), cY - (circleRaidus+roundWidth), cX + circleRaidus+roundWidth, cY +circleRaidus+roundWidth);
        canvas.drawArc(oval, 0f, 360*progress/100, false, arcPaint);
    }
    public synchronized void setProgress( int  progress){
        this.progress=progress;
        postInvalidate();
    }
}

备注:下面是踩坑发生的效果:

//如果将是否填充更改为ture,效果图如下
 canvas.drawArc(oval, 0f, 360*progress/100, true, arcPaint);

这里写图片描述

//如果将是否填充更改为ture,且paint也设置为填充呢?
 arcPaint.setStyle(Paint.Style.FILL);
 canvas.drawArc(oval, 0f, 360*progress/100, true, arcPaint);

这里写图片描述

//不填充扇形的效果
Paint  arcPaint = new Paint();
        arcPaint.setStrokeWidth(roundWidth);
        arcPaint.setColor(Color.BLUE);
        canvas.drawArc(oval, 0f, 360 * progress / 100, false, arcPaint);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值