Android实现自定义倒计时

    最近工作中遇到个要做倒计时60秒的进度条,经过参考别人的资料做出来需求的效果。废话少说先来个效果:

    一定想知道是怎么实现的吧!下面是代码

    
    public class CountDownView extends View {
     //圆轮颜色
     private int mRingColor;
     //默认圆颜色
     private int mRingNormalColor ;
     //圆轮宽度
     private float mRingWidth;
     //圆轮进度值文本大小
     private int mRingProgessTextSize;
     //宽度
     private int mWidth;
     //高度
     private int mHeight;
     private Paint mPaint;
     private Paint paintNormal;
     //圆环的矩形区域
     private RectF mRectF;
     //
     private int mProgessTextColor;
     private int mCountdownTime;
     private float mCurrentProgress;
     private OnCountDownFinishListener mListener;
     private ValueAnimator valueAnimator ;
     
     public CountDownView(Context context) {
      this(context, null);
     }
     
     public CountDownView(Context context, AttributeSet attrs) {
      this(context, attrs, 0);
     }
     
     public CountDownView(Context context, AttributeSet attrs, int defStyleAttr) {
      super(context, attrs, defStyleAttr);
      TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CountDownView);
      mRingColor = a.getColor(R.styleable.CountDownView_ringColor, context.getResources().getColor(R.color.circle_progress));
      mRingWidth = a.getFloat(R.styleable.CountDownView_ringWidth, 8);
      mRingProgessTextSize = a.getDimensionPixelSize(R.styleable.CountDownView_progressTextSize, DisplayUtil.sp2px(context, 12));
      mProgessTextColor = a.getColor(R.styleable.CountDownView_progressTextColor, context.getResources().getColor(R.color.circle_progress));
      mCountdownTime = a.getInteger(R.styleable.CountDownView_countdownTime, 60);
      mRingNormalColor = a.getColor(R.styleable.CountDownView_ringColor, context.getResources().getColor(R.color._circle_progress));
      a.recycle();
      paintNormal = new Paint(Paint.ANTI_ALIAS_FLAG);
      paintNormal.setAntiAlias(true);
      mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
      mPaint.setAntiAlias(true);
      this.setWillNotDraw(false);
     }
     
     public void setCountdownTime(int mCountdownTime) {
      this.mCountdownTime = mCountdownTime;
     }
     
     @Override
     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
      super.onLayout(changed, left, top, right, bottom);
      mWidth = getMeasuredWidth();
      mHeight = getMeasuredHeight();
      mRectF = new RectF(0 + mRingWidth / 2, 0 + mRingWidth / 2,
        mWidth - mRingWidth / 2, mHeight - mRingWidth / 2);
     }
     
     @Override
     protected void onDraw(Canvas canvas) {
      super.onDraw(canvas);
      /**
       *圆环
       */
      //颜色
      mPaint.setColor(mRingColor);
      //空心
      mPaint.setStyle(Paint.Style.STROKE);
      //宽度
      mPaint.setStrokeWidth(mRingWidth);
      /**
       *默认圆环
       */
      //颜色
      paintNormal.setColor(mRingNormalColor);
      //空心
      paintNormal.setStyle(Paint.Style.STROKE);
      //宽度
      paintNormal.setStrokeWidth(mRingWidth);
      canvas.drawArc(mRectF, 360, 360, false, paintNormal);
      canvas.drawArc(mRectF, -90, mCurrentProgress - 360, false, mPaint);
      //绘制文本
      Paint textPaint = new Paint();
      textPaint.setAntiAlias(true);
      textPaint.setTextAlign(Paint.Align.CENTER);
      String text = mCountdownTime - (int) (mCurrentProgress / 360f * mCountdownTime) + "";
      textPaint.setTextSize(mRingProgessTextSize);
      textPaint.setColor(mProgessTextColor);
     
      //文字居中显示
      Paint.FontMetricsInt fontMetrics = textPaint.getFontMetricsInt();
      int baseline = (int) ((mRectF.bottom + mRectF.top - fontMetrics.bottom - fontMetrics.top) / 2);
      canvas.drawText(text, mRectF.centerX(), baseline, textPaint);
     }
     
     private ValueAnimator getValA(long countdownTime) {
      ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 100);
      valueAnimator.setDuration(countdownTime);
      valueAnimator.setInterpolator(new LinearInterpolator());
      valueAnimator.setRepeatCount(0);
      return valueAnimator;
     }
     /**
      * 开始倒计时
      */
     public void startCountDown() {
      setClickable(false);
      valueAnimator = getValA(mCountdownTime * 1000);
      valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
       @Override
       public void onAnimationUpdate(ValueAnimator animation) {
        float i = Float.valueOf(String.valueOf(animation.getAnimatedValue()));
        mCurrentProgress = (int) (360 * (i / 100f));
        invalidate();
       }
      });
      valueAnimator.start();
      valueAnimator.addListener(new AnimatorListenerAdapter() {
       @Override
       public void onAnimationEnd(Animator animation) {
        super.onAnimationEnd(animation);
        //倒计时结束回调
        if (mListener != null) {
         mListener.countDownFinished();
        }
        setClickable(true);
       }
     
      });
     }
     public void setAddCountDownListener(OnCountDownFinishListener mListener) {
      this.mListener = mListener;
     }
     public interface OnCountDownFinishListener {
      void countDownFinished();
     }
     public void stopCountDown(){
      valueAnimator.end();
     }
     
    }

    然后新建一个attr.xml;

    
    <?xml version="1.0" encoding="utf-8"?>
    <resources>
     <declare-styleable name="CountDownView">
      <!--颜色-->
      <attr name="ringColor" format="color" />
      <!-- 进度文本的字体大小 -->
      <attr name="progressTextSize" format="dimension" />
      <!-- 圆环宽度 -->
      <attr name="ringWidth" format="float" />
      <!--进度文本颜色-->
      <attr name="progressTextColor" format="color"/>
      <!--倒计时-->
      <attr name="countdownTime" format="integer"/>
     </declare-styleable>
    </resources>

    这样一个自定义的view就写完了;那怎么用呢;布局就不说了;

    
    losTime.setAddCountDownListener(new CountDownView.OnCountDownFinishListener() {
        @Override
        public void countDownFinished() {
         倒计时结束
        }
       });
    losTime.setCountdownTime(60);
    losTime.startCountDown();

    这样就轻轻松松的跑起来了,希望能帮助到需要的你;

    以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持lingkb。