本人安卓菜鸟,因为学校有一个比赛,所以正在做一个面向高中生的APP。

  今天就是来记录一下倒计时功能的实现。


  一、我首先做了一个类似下拉框的效果,让用户自己选择自己的年级(高一/高二/高三),然后根据相应的年级计算离高考的日期。

  效果如下:  

                               

android倒计时天 安卓倒计时_android倒计时天

                               

android倒计时天 安卓倒计时_System_02

                               

android倒计时天 安卓倒计时_赋值_03

  这里有个问题就是其实这个里面显示的时间和现实中的时间是相差了八个小时的,但是因为我是在模拟器上测试的,所以增加了一段时间。

  后来在打包到手机上一时忘了改,所以才会相差八个小时。


  二、其次来分析一下这个功能的实现原理:

     1.当下与高考时间(在这里我写的设计的是6月7日)之差,运用函数先获得当今时间,在根据年级设计一下高考时间即可。

//获得当前时间 八小时时间差
final Date startDate = new Date(System.currentTimeMillis()+8*60*60*1000);
/**
     * 计算两个日期之间的差
       这个方法是使用了上一位大佬的方法 我一下子没找到这个大佬写这个方法的链接 不好意思
     * */
    private  int countTwoDate(Date startDate,Date endDate){
        Calendar beginCalendar = Calendar.getInstance();
        beginCalendar.setTime(startDate);
        Calendar endCalendar = Calendar.getInstance();
        endCalendar.setTime(endDate);
        long beginTime = beginCalendar.getTime().getTime();
        long endTime = endCalendar.getTime().getTime();
        int betweenDays = (int)((endTime - beginTime) / (1000 * 60 * 60 *24));//先算出两时间的毫秒数之差大于一天的天数

        endCalendar.add(Calendar.DAY_OF_MONTH, -betweenDays);//使endCalendar减去这些天数,将问题转换为两时间的毫秒数之差不足一天的情况
        endCalendar.add(Calendar.DAY_OF_MONTH, -1);//再使endCalendar减去1天
        if(beginCalendar.get(Calendar.DAY_OF_MONTH)==endCalendar.get(Calendar.DAY_OF_MONTH))//比较两日期的DAY_OF_MONTH是否相等
            return betweenDays + 1;	//相等说明确实跨天了
        else
            return betweenDays + 0;	//不相等说明确实未跨天
    }

  根据上述的方法就该知道了,现在我们有了一个startDate,还差一个endDate。   

 

  2.如何根据年级设计高考时间呢?必须是要先获得当前的年份,再根据年级判断相差的年份。

         2.1 我本来是这么做的,设置一个int型变量,如果是高三就是相差一年,如果是高二就是相差两年,如果是高一就相差三年。但是后来想想这样的想法是不准确的。 

         2.2 例如今天是2018-9-15日,高三生的高考时间是在2019-06-07日,确实是相差了一年。但这是因为已经过了高考日期。

                假如今天是2019-2-12,那高考时间时间肯定依然是2019-06-07日,那就是同一年。所以这里应该增加一个比较判断。

        2.3 而且我在这里将高考时间设定为两天,即06-07与06-08。

               所以假如今天是06-07或者今天是06-08,对于高三生来说高考倒计时都应该是0天,绝对不可能出现-1天。

    

//...
  //这里的position是用来判断选择的是哪个年级,因为只有三个年极段,所以范围是从0-2
  //subtract就是声明时间差的那个int型变量
  //subtract2很重要,因为在线程里面有一个很严重的bug就是它会通过subtract--操作改变subtract的值
     switch (position){
                case 0:
                    subtract=3;
                    break;
                case 1:
                    subtract=2;
                    break;
                case 2:
                    subtract=1;
                    break;
            }
    subtract2 = subtract;
//...
//...
            //这是改进的方法的一个代码片段 
            final Date startDate = new Date(System.currentTimeMillis()+8*60*60*1000);
            if(calendar.get(Calendar.MONTH)<6){//这句代码说明了高中生今年高考
                subtract--;
            }else if(calendar.get(Calendar.MONTH)==6){//特殊情况 7号与八号
                if(calendar.get(Calendar.DATE)==7||calendar.get(Calendar.DATE)==8){
                    flag = true;
                }
            }
            year = calendar.get(Calendar.YEAR)+subtract+"";//year我在这里声明为string类型
            DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            //...
//...
//代码片段 flag首先定义为boolean类型 并且赋初值false   
   runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    interval = countTwoDate(startDate, endDate);
                    if(flag){
                        interval = 0;
                    }
                    tvDate.setText("高考倒计时:\n\n"+interval+"天");
                    tvNow.setText(format);
//这行为subtract重新赋值的代码很重要,因为这样可以避免线程的问题
                    subtract = subtract2;
                }
            });
//...

3.高考倒计时应当是随着时间的变迁而变化的,不是一成不变的。

  结合上述代码,再参考某位大佬的实施自动更新时间方法

  再次感谢网上的大佬们的无私奉献!