如何实现一个环形进度条

在之前的工作中,有一个需求是判断已用和剩余油量用环形进度条的方式展示的。改方面的数据是通过串口从底层获取过来的,这边我就随便拿个数来填充就好了。当时由于上级的要求就自己写了一个比较简单的出来。好的,那么今天将跟大家分享如何自定义一个环形进度条,也算是对这方面的知识进行一个总结。下面我们开始实现这个功能。那么首先还是先上代码:

package com.example.circularprogressbar;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Paint.Style;
import android.graphics.RectF;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.View;

public class CircleView extends View {
/**
* 定义画笔
*/
private Paint paint = null;
/**
* 当前弧度
*/
private int currArc = 0;
/**
* 进度百分比
*/
private int progressPrecent = 0;
/**
* 环形进度的半径大小
*/
private int progressCircleRadius = 100;
/**
* 用户设置的进度
*/
private int setProgress = 0;

public CircleView(Context context) {
    super(context);
}

public CircleView(Context context, AttributeSet attrs) {
    super(context, attrs);
    initPaint();
}

public void initPaint() {
    paint = new Paint();
    paint.setAntiAlias(true);
    paint.setStyle(Style.STROKE);// 设置空心
    paint.setTextAlign(Align.CENTER);
    paint.setTextSize(20);
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

@Override
protected void onDraw(Canvas canvas) {
    // 画圆
    drawCircle(canvas);
    // 绘制弧线区域
    drawArc(canvas);
    // 画文字
    drawText(canvas);
    // 画椭圆,参数一是扫描区域,参数二为paint对象
    // drawOval(RectF oval, Paint paint);
}

private void drawArc(Canvas canvas) {
    paint.setColor(Color.RED);
    RectF oval = new RectF(-progressCircleRadius, -progressCircleRadius, progressCircleRadius, progressCircleRadius);
    currArc++;
    /**
     * 参数一是RectF对象,一个矩形区域椭圆形的界限用于定义在形状、大小、弧度;<br/>
     * 参数二是弧度起始角度位置;<br/>
     * 参数三扫描角度开始顺时针测量;<br/>
     * 参数四是如果设置为true,则包括椭圆中心的弧度,并关闭它,如果设置为false,则是一个弧线;<br/>
     * 参数五是Paint对象;
     */
    canvas.drawArc(oval, 270, currArc, false, paint);
}

private void drawText(Canvas canvas) {
    paint.setStrokeWidth(2);
    progressPrecent = (currArc * 100) / 360;
    canvas.drawText(String.valueOf(progressPrecent), 0, 0, paint);
}

private void drawCircle(Canvas canvas) {
    paint.setColor(Color.BLUE);
    paint.setStrokeWidth(20);
    // 将画布位置移动到画布宽度的中心(x),高度的中心-环形进度的半径(y)的坐标点
    canvas.translate(canvas.getWidth() >> 1, (canvas.getHeight() >> 1) - progressCircleRadius);
    /**
     * 参数一是中心点的x轴; <br/>
     * 参数二是中心点的y轴; <br/>
     * 参数三是半径;<br/>
     * 参数四是paint对象;<br/>
     */
    canvas.drawCircle(0, 0, progressCircleRadius, paint);
}

Handler updateViewHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        if (progressPrecent < setProgress) {
            updateViewHandler.sendEmptyMessageDelayed(0, 20);
            invalidate();
        }
    }
};

/**
 * 设置进度值
 * 
 * @param progress
 */
public void setProgress(int progress) {
    updateViewHandler.removeMessages(0);
    // 弧度回退
    currArc = 0;
    // 进度回退
    progressPrecent = 0;
    // 用户设置的进度
    this.setProgress = progress;
    updateViewHandler.sendEmptyMessage(0);
}

public int getProgress() {
    return progressPrecent;
}

@Override
protected void onDetachedFromWindow() {
    updateViewHandler.removeMessages(0);
    super.onDetachedFromWindow();
}

}

这个环形进度条是一个view,是的,它是画出来的view,那么既然是draw出来,我们这边就写一个CircleView继承于view实现该实现的ondraw()方法。首先在构造函数中初始化一个支画笔,然后在ondraw()中去画我们的环形进度条。那么我们再看看效果图:

这里写图片描述

下面来谈谈这个代码思路,当然做法是相当的多,这边只是简单聊聊我这边的原理。
该环形进度条由三部分组成,第一部分是内部蓝色的圆圈,第二部分是覆盖在蓝色圆圈上的红色弧线,还有最后的文本写在圆弧内即可。

在ondraw()中我们定义三个方法:
1、draw蓝色圆形(背景图) 2、draw红色弧线 3、draw文本
蓝色环形部分draw出来之后是放在那里不用改变的,改变的是红色弧线和文本内容

首先我们先将canvas移动到view的中心点,然后拿该点作为圆心画蓝色部分,这边的半径就是draw红色弧线的区域大小,否则将不能恰好覆盖在蓝色环形上,其实这边对于不熟悉绘图API的同学来说就是这里取距离比较麻烦,这边我在代码中已经对绘图API的参数进行了说明了。那么最后就是draw文本内容了,draw文本的位置直接设置在圆心上就可以了。再来就是文本内用,这边是将整个圆划分为100的,但是draw红色弧线是以角度360°来算的,那么转换一下就好了 进度百分比 = (当前弧度 * 100) / 360;
好了,就这么点东西!

最后在xml中应用

这里写图片描述

在activity中

这里写图片描述

源码点击下载

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值