现在倒计时有很多种方法,这里给大家两个方法,代码经过洗礼:

    1.CountDownTimer:调用的时候很简单:timer.start();    timer.cancel();

private TextView vertifyView;  
    private CountDownTimer timer = new CountDownTimer(10000, 1000) {  
  
        @Override  
        public void onTick(long millisUntilFinished) {  
            vertifyView.setText((millisUntilFinished / 1000) + "秒后可重发");  
        }  
  
        @Override  
        public void onFinish() {  
            vertifyView.setEnabled(true);  
            vertifyView.setText("获取验证码");  
        }  
    };
    
    //利用反射动态地改变CountDownTimer类的私有字段mCountdownInterval
private void changeCountdownInterval(long time) {
    try {
        // 反射父类CountDownTimer的mCountdownInterval字段,动态改变回调频率
        Class clazz = Class.forName("android.os.CountDownTimer");
        Field field = clazz.getDeclaredField("mCountdownInterval");
        //从Toast对象中获得mTN变量
        field.setAccessible(true);
        field.set(countDownTimer, time);
    } catch (Exception e) {
        Log.e("Ye", "反射类android.os.CountDownTimer.mCountdownInterval失败:" + e);
    }
}

//利用反射动态地改变CountDownTimer类的私有字段mMillisInFuture
private void changeMillisInFuture(long time) {
    try {
        // 反射父类CountDownTimer的mMillisInFuture字段,动态改变定时总时间
        Class clazz = Class.forName("android.os.CountDownTimer");
        Field field = clazz.getDeclaredField("mMillisInFuture");
        field.setAccessible(true);
        field.set(countDownTimer, time);
    } catch (Exception e) {
        Log.e("Ye", "反射类android.os.CountDownTimer.mMillisInFuture失败: " + e);
    }
}

//调用方法
changeCountdownInterval(500);
changeMillisInFuture(60000);
timer.start();

    附:这种方法只能支持30分钟的倒计时,否则会有延迟。下面是很精准的方法,就是复杂一些~

    2.WeakReference:以系统每次更新时间的一秒的时间差来倒计时。

private H mHandler2 = new H(this);
private static final int MSG_RUN = 189;
private static final int DELAY_MILLIS = 1000;
private long mCurrentTime;

private static class H extends Handler {
    private WeakReference mActivity;
    private long mNextTime;

    public H(MainActivity activity) {
        mActivity = new WeakReference(activity);
    }

    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        MainActivity activity = mActivity.get();
        if (activity == null || msg.what != MSG_RUN) {
            return;
        }
        if (activity.decrTime(SystemClock.uptimeMillis() - mNextTime)) {
            mNextTime = SystemClock.uptimeMillis();
            sendEmptyMessageDelayed(MSG_RUN, DELAY_MILLIS);
        }
    }
}

    支持传int hour int min int second和直接传时间戳long 60000 ms,另外给大家提供一个时间的util,希望能帮到你们。

package com.example.p027_daojishi.util;

import java.util.ArrayList;
import java.util.List;

public class TimeUtil {

    /**
     * @param ms
     * @return result[day, hour, minute, second]
     */
    public static long[] compute(long ms) {
        long[] result = new long[4];

        // day
        result[0] = ms / (24 * 60 * 60 * 1000);
        ms = ms % (24 * 60 * 60 * 1000);

        // hour
        result[1] = ms / (60 * 60 * 1000);
        ms = ms % (60 * 60 * 1000);

        // minute
        result[2] = ms / (60 * 1000);
        ms = ms % (60 * 1000);

        // second
        result[3] = ms / 1000;

        return result;
    }

    /**
     * @param
     * @return void
     * @throws Exception
     * @throws
     * @Description: 设置倒计时的时长
     */
    public static int[] setTime(int hour) {
        int[] result = new int[2];
        //hour 十位
        result[0] = hour / 10;
        //hour 个位
        result[1] = hour - hour / 10 * 10;
        return result;
    }

    /**
     * TimePicker设置初始化数据bufen
     *
     * @param hour
     * @param num
     */
    public static List initTpTime(final int hour, final int num) {
        List data = new ArrayList() {
            {
                for (int i = hour; i < num; i++) {
                    add(i + "");
                }
            }
        };
        return data;
    }

    /**
     * TimePicker设置起始数据bufen
     * tp_hour.setData(setTpTime(hour, 24));
     * tp_min.setData(setTpTime(min, 60));
     * tp_sec.setData(setTpTime(sec, 60));
     * hour=12 num=24
     * min=59 num=60
     * sec=59 num=60
     *
     * @param hour
     * @param num
     */
    public static List setTpTime(final int hour, final int num) {
        List data = new ArrayList() {
            {
                for (int i = hour; i < num; i++) {
                    add(i + "");
                }
                for (int i = 0; i < hour; i++) {
                    add(i + "");
                }
            }
        };
        return data;
    }

    /**
     * 获取倒计时布局的hour min sec bufen 10 : 12 : 59 02 : 01 : 02 转成 long
     *
     * @param timeStr
     * @return
     */
    public static long getTimeStrSec(String timeStr) {
        if (timeStr == null || timeStr.length() < 5) {
            return -1L;
        }
        String[] times = timeStr.split(":");
        if (times == null || times.length != 3) {
            return -1L;
        }
        if (times[0] == null || times[1] == null || times[2] == null) {
            return -1L;
        }
        long hour = Long.parseLong(times[0].trim());
        long minute = Long.parseLong(times[1].trim());
        long second = Long.parseLong(times[2].trim());
        return hour * 60L * 60L + minute * 60 + second;
    }

    /**
     * 1 2 3 转 01 02 03
     *
     * @param i
     * @return
     */
    public static String time_change_one(long i) {
        String s = String.format("%02d", i);
        return s;
    }

    /**
     * 01 02 12 zhuang 1 2 12
     *
     * @param data
     * @return
     */
    public static String time_change_two(String data) {
        char[] chars = data.toCharArray();
        if (String.valueOf(chars[0]).equals("0")) {
            data = String.valueOf(chars[1]);
        } else {
            data = data;
        }
        return data;
    }

}

    附:TimerPicker初始化

tp_hour.setData(initTpTime(0, 24));
tp_min.setData(initTpTime(0, 60));
tp_sec.setData(initTpTime(0, 60));

    总结:其实倒计时在订单统一时间的时候是需要精确的计算,不然差的时间加上网络的推送延时是有可能影响结算结果的,以上方法希望能帮到你。

    Android Studio - 第四十四期 倒计时_第1张图片

    地址:https://github.com/geeklx/MyApplication/tree/master/p027_daojishi_manifestPlaceholders