android 圆形倒计时实现

时间:2022-01-26 22:01:01

仿照某些APP,设计在Splash页面右上角上添加圆形倒计时器,实现:

1、圈内时间倒计时

2、圆环动态增长

实现方式:

1、CircleTextView:
继承自TextView类,接收从外部提供的当前进度百分比,通过重绘canvas的方式模拟圆环自动增长的效果。
具体实现如下:

声明自定义属性:
<span style="white-space:pre">	</span>TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.CircleTextView);
        width = ta.getDimension(R.styleable.CircleTextView_width, 1);                      //圆环宽度
        stroke = ta.getColor(R.styleable.CircleTextView_stroke, Color.RED);                //圆环颜色
        background = ta.getColor(R.styleable.CircleTextView_back, Color.TRANSPARENT);      //canvas背景
        million_time = ta.getFloat(R.styleable.CircleTextView_million_time, 3000);         //倒计时时间
        per_million_time = ta.getFloat(R.styleable.CircleTextView_per_million_time, 100);  //倒计时间隔
        seq = ta.getInt(R.styleable.CircleTextView_seq, 1);                                //顺序(positive:正序,negative:倒序)
        ta.recycle();

绘制canvas:
    @Override
    protected void onDraw(Canvas canvas) {
        //绘制背景
        paint.setColor(background);
        paint.setStyle(Paint.Style.FILL);
        canvas.drawCircle(canvas.getWidth() / 2, canvas.getHeight() / 2, canvas.getWidth() / 2, paint);

        //绘制初始外框
        paint.setColor(Color.LTGRAY);
        canvas.drawColor(Color.TRANSPARENT);
        paint.setStrokeWidth(width);
        paint.setStyle(Paint.Style.STROKE);

        //绘制进度条
        canvas.drawArc(rectF, -90, 360, false, paint);
        paint.setColor(stroke);
        canvas.drawArc(rectF, -90, per * 360, false, paint);

        super.onDraw(canvas);
    }

更新canvas:
    private void drawProgress(float p) {
        this.per = p;
        this.postInvalidate();
    }

这样一个简单的自定义TextView控件就做好了。
下面,需要给这个控件添加倒计时功能,需要用到CountDownTimer类,声明一个内部私有类MyCountDownTimer:
private class MyCountDownTimer extends CountDownTimer {

        /**
         * @param millisInFuture    The number of millis in the future from the call
         *                          to {@link #start()} until the countdown is done and {@link #onFinish()}
         *                          is called.
         * @param countDownInterval The interval along the way to receive
         *                          {@link #onTick(long)} callbacks.
         */
        public MyCountDownTimer(long millisInFuture, long countDownInterval) {
            super(millisInFuture, countDownInterval);
        }

        @Override
        public void onTick(long millisUntilFinished) {
            drawProgress(1 - millisUntilFinished / million_time);
            if(seq == 0)
            ct.setText((int) (million_time - millisUntilFinished) / 1000 + "s");
            else
                ct.setText(((int) (millisUntilFinished) / 1000 + 1) + "s");
        }

        @Override
        public void onFinish() {
            ct.drawProgress(1);
            if(seq == 0) {
                ct.setText((int) (million_time / 1000) + "s");
            } else {
                ct.setText("0s");
            }
        }
添加倒计时完成的监听功能:
<span style="white-space:pre">	</span>public interface ResultListener {
    <span style="white-space:pre">		</span>public void onBegin();
    <span style="white-space:pre">		</span>public void onFinish();
<span style="white-space:pre">	</span>}
同时,在CirCleTextView中,添加此listener,并在控件的start()函数中传递onBegin消息及倒计时类中的onFinish()函数中传递onFinish()消息。