注意:调用直接在布局文件中用就行,setDuration直接用,也可以自己修改,颜色可以自己修改
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.os.CountDownTimer;
import android.util.AttributeSet;
import android.view.View;
import com.iqilu.phonetoken.R;
public class CountDownProgressBar extends View {
/**
* 当前进度值
*/
private int currentValue ;
/**
* 每次扫过的角度,用来设置进度条圆弧所对应的圆心角,alphaAngle=(currentValue/maxValue)*360
*/
private float alphaAngle;
/**
* 圆环的宽度
*/
private int circleWidth = 10;
/**
* 画圆弧的画笔
*/
private Paint circlePaint;
/**
* 画文字的画笔
*/
private Paint textPaint;
private OnFinishListener listener;
private int time_x,time_y,name_y,number_y,home_y;
private CountDownTimer countDownTimer;
private String keyName,keyNumber,sysName = "111";
public CountDownProgressBar(Context context) {
this(context, null);
}
public CountDownProgressBar(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CountDownProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
circlePaint = new Paint();
circlePaint.setAntiAlias(true); // 抗锯齿
circlePaint.setDither(true); // 防抖动
circlePaint.setStrokeWidth(circleWidth);//画笔宽度
textPaint = new Paint();
textPaint.setAntiAlias(true);
textPaint.setDither(true);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// 分别获取期望的宽度和高度,并取其中较小的尺寸作为该控件的宽和高,并且不超过屏幕宽高
int widthPixels = this.getResources().getDisplayMetrics().widthPixels;//获取屏幕宽
int heightPixels = this.getResources().getDisplayMetrics().heightPixels;//获取屏幕高
int width = MeasureSpec.getSize(widthMeasureSpec);
int hedight = MeasureSpec.getSize(heightMeasureSpec);
int minWidth = Math.min(widthPixels, width);
int minHedight = Math.min(heightPixels, hedight);
setMeasuredDimension(Math.min(minWidth, minHedight), Math.min(minWidth, minHedight));
}
@Override
protected void onDraw(Canvas canvas) {
time_x = this.getWidth() / 2;
time_y = this.getHeight();
number_y = time_y/2;
name_y = number_y/2;
home_y = number_y + 100;
int radius = time_x - circleWidth / 2-10;
drawCircle(canvas, radius); // 绘制进度圆弧
drawText(canvas);
}
/**
* 绘制进度圆弧
*
* @param canvas 画布对象
* time_x 圆心的x和y坐标
* @param radius 圆的半径
*/
private void drawCircle(Canvas canvas, int radius) {
circlePaint.setShader(null); // 清除上一次的shader
circlePaint.setColor(getContext().getColor(R.color.countdown_back)); // 设置底部圆环的颜色,这里使用第一种颜色
circlePaint.setStyle(Paint.Style.STROKE); // 设置绘制的圆为空心
canvas.drawCircle(time_x, time_x, radius, circlePaint); // 画底部的空心圆
RectF oval = new RectF(time_x - radius, time_x - radius, time_x + radius, time_x + radius); // 圆的外接正方形
circlePaint.setColor(getContext().getColor(R.color.mytoken_blue)); // 设置圆弧的颜色
circlePaint.setStrokeCap(Paint.Cap.ROUND); // 把每段圆弧改成圆角的
alphaAngle = currentValue * 6;
canvas.drawArc(oval,90, alphaAngle, false, circlePaint);
}
/**
* 绘制文字
*
* @param canvas 画布对象
*/
private void drawText(Canvas canvas) {
//时间
String percent;
percent = currentValue + "/" + "60s";
textPaint.setTextSize(36); // 设置要绘制的文字大小
textPaint.setTextAlign(Paint.Align.CENTER); // 设置文字居中,文字的x坐标要注意
textPaint.setColor(getContext().getColor(R.color.mytoken_blue)); // 设置文字颜色
textPaint.setStrokeWidth(0); // 注意此处一定要重新设置宽度为0,否则绘制的文字会重叠
Rect bounds = new Rect(); // 文字边框
textPaint.getTextBounds(percent, 0, percent.length(), bounds); // 获得绘制文字的边界矩形
canvas.drawText(percent, time_x, time_y-30, textPaint); // 绘制表示进度的文字
//号
textPaint.setTextSize(125);
textPaint.setTypeface(Typeface.DEFAULT_BOLD);
canvas.drawText(keyNumber, time_x, number_y, textPaint); // 绘制表示进度的文字
//名
textPaint.setTextSize(28);
textPaint.setTypeface(Typeface.DEFAULT);
textPaint.setColor(getContext().getColor(R.color.text_color_33));
canvas.drawText("NO:"+keyName, time_x, name_y, textPaint); // 绘制表示进度的文字
//固定
textPaint.setTextSize(26);
textPaint.setTypeface(Typeface.DEFAULT);
textPaint.setColor(getContext().getColor(R.color.text_gray));
canvas.drawText(sysName, time_x, home_y, textPaint); // 绘制表示进度的文字
}
/**
* 按进度显示百分比,可选择是否启用数字动画
*countDownTimer 需要cancel然后new出来
* @param duration 动画时长
*/
public void setDuration(int duration,String keyName,String keyNumber, OnFinishListener listener) {
this.keyName = keyName;
this.keyNumber = keyNumber;
this.listener = listener;
currentValue = duration/1000;
if(countDownTimer!=null){
countDownTimer.cancel();
countDownTimer = null;
}
countDownTimer = new CountDownTimer(duration,1000) {
@Override
public void onTick(long millisUntilFinished) {
currentValue--;
invalidate();
}
@Override
public void onFinish() {
CountDownProgressBar.this.listener.onFinish();
}
};
countDownTimer.start();
}
public interface OnFinishListener {
void onFinish();
}
}
Activity中
countDownProgressBar.setDuration(timeCount,tokenName,secretNumber,new CountDownProgressBar.OnFinishListener() {
@Override
public void onFinish() {
timeCount = 60*1000;
countDownProgressBar.setDuration(timeCount,tokenName,secretNumber,this);
//处理自己的方法
}
});
本文介绍了一种自定义的Android倒计时进度条组件的实现方法,包括绘制圆形进度条、文字显示等功能,并提供了完整的代码示例。
701

被折叠的 条评论
为什么被折叠?



