仿淘宝倒计时

在前面的文章中,我们分析了淘宝Android客户端的一些界面实现和用户体验,今天这篇文章,主要介绍如何使用自定义控件,实现抢购倒计时的功能。

    首先,我们看一下实现的效果。

    


    实现效果很简单哈,就是一个倒计时的自定义控件。

    下面简单介绍一下实现的思路。

    首先,显示时间使用的是Textview,因为没有很特殊的效果,因此,我们可以自己写一个简单的布局文件,来作为显示的界面。

    而关于时间的变更,我们使用timer类就可以实现,用一个1000毫秒的Timer,每过一秒,更新一下界面即可。

    但是在更新时间的显示数字的时候,有一个问题需要注意,我的思路是用6个Textview来显示时间,因此,时分秒的十位数字和个位数字需要单独显示,个位上显示的数字是0-9,十位上显示的数字范围是0-5,所以需要分开实现。

    当秒的十位个位都是0的时候,在过一秒,分的个位就要减一,这就涉及到借位的问题,因此,每变更一次数字,都需要判断是否需要借位。

    具体的实现思路,大家还是看代码吧。

    

[java]  view plain  copy
 
  在CODE上查看代码片 派生到我的代码片
  1. /* 
  2.  * Copyright (c) 2014, 青岛司通科技有限公司 All rights reserved. 
  3.  * File Name:RushBuyCountDownTimerView.java 
  4.  * Version:V1.0 
  5.  * Author:zhaokaiqiang 
  6.  * Date:2014-9-26 
  7.  */  
  8. package com.qust.widght;  
  9.   
  10. import java.util.Timer;  
  11. import java.util.TimerTask;  
  12.   
  13. import android.annotation.SuppressLint;  
  14. import android.content.Context;  
  15. import android.os.Handler;  
  16. import android.os.Message;  
  17. import android.util.AttributeSet;  
  18. import android.view.LayoutInflater;  
  19. import android.view.View;  
  20. import android.widget.LinearLayout;  
  21. import android.widget.TextView;  
  22. import android.widget.Toast;  
  23.   
  24. import com.qust.rushbuycountdowntimerview.R;  
  25.   
  26. @SuppressLint("HandlerLeak")  
  27. public class RushBuyCountDownTimerView extends LinearLayout {  
  28.   
  29.     // 小时,十位  
  30.     private TextView tv_hour_decade;  
  31.     // 小时,个位  
  32.     private TextView tv_hour_unit;  
  33.     // 分钟,十位  
  34.     private TextView tv_min_decade;  
  35.     // 分钟,个位  
  36.     private TextView tv_min_unit;  
  37.     // 秒,十位  
  38.     private TextView tv_sec_decade;  
  39.     // 秒,个位  
  40.     private TextView tv_sec_unit;  
  41.   
  42.     private Context context;  
  43.   
  44.     private int hour_decade;  
  45.     private int hour_unit;  
  46.     private int min_decade;  
  47.     private int min_unit;  
  48.     private int sec_decade;  
  49.     private int sec_unit;  
  50.     // 计时器  
  51.     private Timer timer;  
  52.   
  53.     private Handler handler = new Handler() {  
  54.   
  55.         public void handleMessage(Message msg) {  
  56.             countDown();  
  57.         };  
  58.     };  
  59.   
  60.     public RushBuyCountDownTimerView(Context context, AttributeSet attrs) {  
  61.         super(context, attrs);  
  62.   
  63.         this.context = context;  
  64.         LayoutInflater inflater = (LayoutInflater) context  
  65.                 .getSystemService(Context.LAYOUT_INFLATER_SERVICE);  
  66.         View view = inflater.inflate(R.layout.view_countdowntimer, this);  
  67.   
  68.         tv_hour_decade = (TextView) view.findViewById(R.id.tv_hour_decade);  
  69.         tv_hour_unit = (TextView) view.findViewById(R.id.tv_hour_unit);  
  70.         tv_min_decade = (TextView) view.findViewById(R.id.tv_min_decade);  
  71.         tv_min_unit = (TextView) view.findViewById(R.id.tv_min_unit);  
  72.         tv_sec_decade = (TextView) view.findViewById(R.id.tv_sec_decade);  
  73.         tv_sec_unit = (TextView) view.findViewById(R.id.tv_sec_unit);  
  74.   
  75.     }  
  76.   
  77.     /** 
  78.      *  
  79.      * @Description: 开始计时 
  80.      * @param 
  81.      * @return void 
  82.      * @throws 
  83.      */  
  84.     public void start() {  
  85.   
  86.         if (timer == null) {  
  87.             timer = new Timer();  
  88.             timer.schedule(new TimerTask() {  
  89.   
  90.                 @Override  
  91.                 public void run() {  
  92.                     handler.sendEmptyMessage(0);  
  93.                 }  
  94.             }, 01000);  
  95.         }  
  96.     }  
  97.   
  98.     /** 
  99.      *  
  100.      * @Description: 停止计时 
  101.      * @param 
  102.      * @return void 
  103.      * @throws 
  104.      */  
  105.     public void stop() {  
  106.         if (timer != null) {  
  107.             timer.cancel();  
  108.             timer = null;  
  109.         }  
  110.     }  
  111.   
  112.     /** 
  113.      * @throws Exception 
  114.      *  
  115.      * @Description: 设置倒计时的时长 
  116.      * @param 
  117.      * @return void 
  118.      * @throws 
  119.      */  
  120.     public void setTime(int hour, int min, int sec) {  
  121.   
  122.         if (hour >= 60 || min >= 60 || sec >= 60 || hour < 0 || min < 0  
  123.                 || sec < 0) {  
  124.             throw new RuntimeException("Time format is error,please check out your code");  
  125.         }  
  126.   
  127.         hour_decade = hour / 10;  
  128.         hour_unit = hour - hour_decade * 10;  
  129.   
  130.         min_decade = min / 10;  
  131.         min_unit = min - min_decade * 10;  
  132.   
  133.         sec_decade = sec / 10;  
  134.         sec_unit = sec - sec_decade * 10;  
  135.   
  136.         tv_hour_decade.setText(hour_decade + "");  
  137.         tv_hour_unit.setText(hour_unit + "");  
  138.         tv_min_decade.setText(min_decade + "");  
  139.         tv_min_unit.setText(min_unit + "");  
  140.         tv_sec_decade.setText(sec_decade + "");  
  141.         tv_sec_unit.setText(sec_unit + "");  
  142.   
  143.     }  
  144.   
  145.     /** 
  146.      *  
  147.      * @Description: 倒计时 
  148.      * @param 
  149.      * @return boolean 
  150.      * @throws 
  151.      */  
  152.     private void countDown() {  
  153.   
  154.         if (isCarry4Unit(tv_sec_unit)) {  
  155.             if (isCarry4Decade(tv_sec_decade)) {  
  156.   
  157.                 if (isCarry4Unit(tv_min_unit)) {  
  158.                     if (isCarry4Decade(tv_min_decade)) {  
  159.   
  160.                         if (isCarry4Unit(tv_hour_unit)) {  
  161.                             if (isCarry4Decade(tv_hour_decade)) {  
  162.                                 Toast.makeText(context, "时间到了",  
  163.                                         Toast.LENGTH_SHORT).show();  
  164.                                 stop();  
  165.                             }  
  166.                         }  
  167.                     }  
  168.                 }  
  169.             }  
  170.         }  
  171.     }  
  172.   
  173.     /** 
  174.      *  
  175.      * @Description: 变化十位,并判断是否需要进位 
  176.      * @param 
  177.      * @return boolean 
  178.      * @throws 
  179.      */  
  180.     private boolean isCarry4Decade(TextView tv) {  
  181.   
  182.         int time = Integer.valueOf(tv.getText().toString());  
  183.         time = time - 1;  
  184.         if (time < 0) {  
  185.             time = 5;  
  186.             tv.setText(time + "");  
  187.             return true;  
  188.         } else {  
  189.             tv.setText(time + "");  
  190.             return false;  
  191.         }  
  192.   
  193.     }  
  194.   
  195.     /** 
  196.      *  
  197.      * @Description: 变化个位,并判断是否需要进位 
  198.      * @param 
  199.      * @return boolean 
  200.      * @throws 
  201.      */  
  202.     private boolean isCarry4Unit(TextView tv) {  
  203.   
  204.         int time = Integer.valueOf(tv.getText().toString());  
  205.         time = time - 1;  
  206.         if (time < 0) {  
  207.             time = 9;  
  208.             tv.setText(time + "");  
  209.             return true;  
  210.         } else {  
  211.             tv.setText(time + "");  
  212.             return false;  
  213.         }  
  214.   
  215.     }  
  216. }  

   项目在我的github上,大家可以下载,也可以提交BUG。

   项目地址

    https://github.com/ZhaoKaiQiang/RushBuyCountDownTimerView

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值