Android 倒计时功能,完美解决系统时间更改后,倒计时不准问题。

Android 倒计时功能,完美解决系统时间更改后,倒计时不准问题。

1、Android倒计时大家一下子就会想到使用:timer.schedule();

我们查看schedule实现的源码:sched(task, System.currentTimeMillis()+delay, 0);

System.currentTimeMillis()这个玩意就是使用系统时间来做的,假如我们更改了系统时间,那倒计时就会出现问题!不信大家可以试试哈。。。。

2、如何解决这个问题呢?当然Android系统还提供了一个时间:开机时间  SystemClock.elapsedRealtime() 这个时间是开机时就记录的,和系统时间就没毛关系啦,更改系统时间也不会把开机时间更改的。

3、所以我们想要实现倒计时不被系统时间更改影响的话就可以使用到开机时间了。当然Android api也封装了使用开机时间的倒计时:CountDownTimer

new CountDownTimer(timeMiao, 1000) {
    @Override
    public void onTick(long millisUntilFinished) {
        
    }

    @Override
    public void onFinish() {
        
    }
}.start();

好啦不废话直接上代码:

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.os.CountDownTimer;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.widget.LinearLayout;
import android.widget.TextView;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;

import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;

/**
*
* 倒计时控件
*/
public class TimeDownView extends LinearLayout {
    private Context mContext;
    private static final String TIME = "mm:ss";
    private static final String MILLION = "S";
    private String time = "00:00:00";
    private String million = "0";
    private CountDownTimer downTimer;
    private DateFormat df, df2;
    private TextView mText, mText2;

    private int txtColor, txtBg, txtSize;
    private int txtMillionColor, txtMillionBg, txtMillionSize;
    private boolean millionShow = false;
    private boolean isTimeDownOver = false;
    private long millisSeconds = 0;

    public TimeDownView(Context context) {
        super(context);
        initView(context, null);
    }

    public TimeDownView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initView(context, attrs);
    }

    public TimeDownView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        initView(context, attrs);
    }

    private void initView(Context context, AttributeSet attrs) {
        mContext = context;

        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.TimeView);
        millionShow = ta.getBoolean(R.styleable.TimeView_million_show, false);
        txtColor = ta.getInt(R.styleable.TimeView_txt_color, Color.RED);
        txtBg = ta.getInt(R.styleable.TimeView_txt_bg, Color.WHITE);
        txtSize = ta.getInt(R.styleable.TimeView_txt_size, 13);


        mText = new TextView(mContext);
        mText.setTextColor(txtColor);
        mText.setTextSize(txtSize);
        mText.setBackgroundColor(txtBg);
        mText.setText(time);

        addView(mText);
        df = createDateFormat(TIME);

        if (millionShow) {
            txtMillionColor = ta.getInt(R.styleable.TimeView_txt_million_color, Color.RED);
            txtMillionBg = ta.getInt(R.styleable.TimeView_txt_million_bg, Color.WHITE);
            txtMillionSize = ta.getInt(R.styleable.TimeView_txt_million_size, 13);
            df2 = createDateFormat(MILLION);

            mText2 = new TextView(mContext);
            mText2.setTextColor(txtMillionColor);
            mText2.setTextSize(txtMillionSize);
            mText2.setBackgroundColor(txtMillionBg);
            mText2.setText(million);
            mText2.setPadding(5, 0, 5, 0);

            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT);
            params.leftMargin = 10;
            mText2.setLayoutParams(params);

            addView(mText2);
        }
    }

    public void startTime(long timeMillionMiao) {
        if (timeMillionMiao < 1000) {
            isTimeDownOver = true;
            invalidate(0);
            return;
        }
        if (downTimer != null) {
            downTimer.onFinish();
            downTimer.cancel();
        }
        downTimer = new CountDownTimer(timeMillionMiao, millionShow ? 100 : 1000) {
            @Override
            public void onTick(long millisUntilFinished) {
                isTimeDownOver = false;
                invalidate(millisUntilFinished);
            }

            @Override
            public void onFinish() {
                isTimeDownOver = true;
                invalidate(0);
            }
        }.start();
    }

    public void invalidate(long millisSeconds) {
        this.millisSeconds = millisSeconds;
        mText.setText(formatTime(millisSeconds));

        if (millionShow) {
            Date date = new Date(millisSeconds);
            mText2.setText(df2.format(date));
        }
    }

    private DateFormat createDateFormat(String pattern) {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        TimeZone gmt = TimeZone.getTimeZone("GMT");//关键所在
        sdf.setTimeZone(gmt);
        sdf.setLenient(true);
        return sdf;
    }

    /**
     * 毫秒转化时分秒
     */
    public static String formatTime(long ms) {
        int ss = 1000;
        int mi = ss * 60;
        int hh = mi * 60;
        int dd = hh * 24;

        long day = ms / dd;
        long hour = (ms - day * dd) / hh;
        long minute = (ms - day * dd - hour * hh) / mi;
        long second = (ms - day * dd - hour * hh - minute * mi) / ss;
        long milliSecond = ms - day * dd - hour * hh - minute * mi - second * ss;

        hour = day * 24 + hour;

        String strDay = day < 10 ? "0" + day : "" + day; //天
        String strHour = hour < 10 ? "0" + hour : "" + hour;//小时
        String strMinute = minute < 10 ? "0" + minute : "" + minute;//分钟
        String strSecond = second < 10 ? "0" + second : "" + second;//秒
        String strMilliSecond = milliSecond < 10 ? "0" + milliSecond : "" + milliSecond;//毫秒
        strMilliSecond = milliSecond < 100 ? "0" + strMilliSecond : "" + strMilliSecond;

        return strHour + ":" + strMinute + ":" + strSecond;
    }

    public boolean isTimeDownOver() {
        return isTimeDownOver;
    }

    public long getMillisSeconds() {
        return millisSeconds;
    }
}

以上代码,我是把倒计时做成一个控件使用的,哈哈方便些。。。。有不足之处欢迎大家吐槽哈。。。。。。

最近用RxJava2也实现倒计时功能,很清爽:https://blog.csdn.net/Jocerly/article/details/84836104

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值