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. 自定义控件
  2. Android 调用系统Email --多附件
  3. Android图形系统的分析与移植 -- 六、双缓冲framebuffer的实现
  4. Android如何获得系统(system)权限
  5. Android 中自定义控件和属性(attr.xml,declare-styleable,TypedA
  6. Android 音频系统:从 AudioTrack 到 AudioFlinger
  7. Android深入浅出系列课程---Lesson7 LLY110426_Android系统启动

随机推荐

  1. 观摩Android的多层框架体系
  2. Android客户端处理服务器端返回的Json格
  3. onTouchEvent、onClick和onLongClick的调
  4. android SharedPreference的简单使用(登陆
  5. ScrollView can host only one direct ch
  6. Android 内部存储相关的函数(getCacheDir,
  7. Android(安卓)Studio maven-metadata.xml
  8. android Fragment实现
  9. android 蓝牙源码分析
  10. Android(安卓)4.0调用http接口php网站的a