目前越来越多的app在注册或是进行对应操作时,要求获取短信验证码,在点击了获取短信验证码的按钮后,就是出现倒计时,比如倒计时120S,在倒计时 期间内,按钮点击是无效的,当倒计时结束后,如果你没有获取到验证码,可以再次点击。实现倒计时的方法很多,我们今天就通过继承 android. os.CountDownTimer类来实现!

首先看下我们封装的倒计时工具类,主要为了在多个地方用到的话,用了多个构造方法,就是为了使用更灵活,只要传入对数就可以调用了:

[?](http://www.open-open.com/code/view/1426335036826#)
<table border="0" cellspacing="0" cellpadding="0">
  <tr>
    <td class="gutter">
      <div class="line number1 index0 alt2">
        1
      </div>
      
      <div class="line number2 index1 alt1">
        2
      </div>
      
      <div class="line number3 index2 alt2">
        3
      </div>
      
      <div class="line number4 index3 alt1">
        4
      </div>
      
      <div class="line number5 index4 alt2">
        5
      </div>
      
      <div class="line number6 index5 alt1">
        6
      </div>
      
      <div class="line number7 index6 alt2">
        7
      </div>
      
      <div class="line number8 index7 alt1">
        8
      </div>
      
      <div class="line number9 index8 alt2">
        9
      </div>
      
      <div class="line number10 index9 alt1">
        10
      </div>
      
      <div class="line number11 index10 alt2">
        11
      </div>
      
      <div class="line number12 index11 alt1">
        12
      </div>
      
      <div class="line number13 index12 alt2">
        13
      </div>
      
      <div class="line number14 index13 alt1">
        14
      </div>
      
      <div class="line number15 index14 alt2">
        15
      </div>
      
      <div class="line number16 index15 alt1">
        16
      </div>
      
      <div class="line number17 index16 alt2">
        17
      </div>
      
      <div class="line number18 index17 alt1">
        18
      </div>
      
      <div class="line number19 index18 alt2">
        19
      </div>
      
      <div class="line number20 index19 alt1">
        20
      </div>
      
      <div class="line number21 index20 alt2">
        21
      </div>
      
      <div class="line number22 index21 alt1">
        22
      </div>
      
      <div class="line number23 index22 alt2">
        23
      </div>
      
      <div class="line number24 index23 alt1">
        24
      </div>
      
      <div class="line number25 index24 alt2">
        25
      </div>
      
      <div class="line number26 index25 alt1">
        26
      </div>
      
      <div class="line number27 index26 alt2">
        27
      </div>
      
      <div class="line number28 index27 alt1">
        28
      </div>
      
      <div class="line number29 index28 alt2">
        29
      </div>
      
      <div class="line number30 index29 alt1">
        30
      </div>
      
      <div class="line number31 index30 alt2">
        31
      </div>
      
      <div class="line number32 index31 alt1">
        32
      </div>
      
      <div class="line number33 index32 alt2">
        33
      </div>
      
      <div class="line number34 index33 alt1">
        34
      </div>
      
      <div class="line number35 index34 alt2">
        35
      </div>
      
      <div class="line number36 index35 alt1">
        36
      </div>
      
      <div class="line number37 index36 alt2">
        37
      </div>
      
      <div class="line number38 index37 alt1">
        38
      </div>
      
      <div class="line number39 index38 alt2">
        39
      </div>
      
      <div class="line number40 index39 alt1">
        40
      </div>
      
      <div class="line number41 index40 alt2">
        41
      </div>
      
      <div class="line number42 index41 alt1">
        42
      </div>
      
      <div class="line number43 index42 alt2">
        43
      </div>
      
      <div class="line number44 index43 alt1">
        44
      </div>
      
      <div class="line number45 index44 alt2">
        45
      </div>
      
      <div class="line number46 index45 alt1">
        46
      </div>
      
      <div class="line number47 index46 alt2">
        47
      </div>
      
      <div class="line number48 index47 alt1">
        48
      </div>
      
      <div class="line number49 index48 alt2">
        49
      </div>
      
      <div class="line number50 index49 alt1">
        50
      </div>
      
      <div class="line number51 index50 alt2">
        51
      </div>
      
      <div class="line number52 index51 alt1">
        52
      </div>
      
      <div class="line number53 index52 alt2">
        53
      </div>
      
      <div class="line number54 index53 alt1">
        54
      </div>
      
      <div class="line number55 index54 alt2">
        55
      </div>
      
      <div class="line number56 index55 alt1">
        56
      </div>
      
      <div class="line number57 index56 alt2">
        57
      </div>
      
      <div class="line number58 index57 alt1">
        58
      </div>
      
      <div class="line number59 index58 alt2">
        59
      </div>
      
      <div class="line number60 index59 alt1">
        60
      </div>
      
      <div class="line number61 index60 alt2">
        61
      </div>
      
      <div class="line number62 index61 alt1">
        62
      </div>
      
      <div class="line number63 index62 alt2">
        63
      </div>
      
      <div class="line number64 index63 alt1">
        64
      </div>
    </td>
    
    <td class="code">
      <div class="container">
        <div class="line number1 index0 alt2">
          `public` `class` `MyCountTimer ``extends` `CountDownTimer {`
        </div>
        
        <div class="line number2 index1 alt1">
          `public` `static` `final` `int` `TIME_COUNT = ``121000``;``//时间防止从119s开始显示(以倒计时120s为例子)`
        </div>
        
        <div class="line number3 index2 alt2">
          `private` `TextView btn;`
        </div>
        
        <div class="line number4 index3 alt1">
          `private` `int` `endStrRid;`
        </div>
        
        <div class="line number5 index4 alt2">
          `private` `int` `normalColor, timingColor;``//未计时的文字颜色,计时期间的文字颜色`
        </div>
        
        <div class="line number6 index5 alt1">
        </div>
        
        <div class="line number7 index6 alt2">
          `/**`
        </div>
        
        <div class="line number8 index7 alt1">
          `* 参数 millisInFuture         倒计时总时间(如60S,120s等)`
        </div>
        
        <div class="line number9 index8 alt2">
          `* 参数 countDownInterval    渐变时间(每次倒计1s)`
        </div>
        
        <div class="line number10 index9 alt1">
        </div>
        
        <div class="line number11 index10 alt2">
          `        ``* 参数 btn               点击的按钮(因为Button是TextView子类,为了通用我的参数设置为TextView)`
        </div>
        
        <div class="line number12 index11 alt1">
        </div>
        
        <div class="line number13 index12 alt2">
          `        ``* 参数 endStrRid   倒计时结束后,按钮对应显示的文字`
        </div>
        
        <div class="line number14 index13 alt1">
          `*/`
        </div>
        
        <div class="line number15 index14 alt2">
          `public` `MyCountTimer (``long` `millisInFuture, ``long` `countDownInterval, TextView btn, ``int` `endStrRid) {`
        </div>
        
        <div class="line number16 index15 alt1">
          `super``(millisInFuture, countDownInterval);`
        </div>
        
        <div class="line number17 index16 alt2">
          `this``.btn = btn;`
        </div>
        
        <div class="line number18 index17 alt1">
          `this``.endStrRid = endStrRid;`
        </div>
        
        <div class="line number19 index18 alt2">
          `}`
        </div>
        
        <div class="line number20 index19 alt1">
        </div>
        
        <div class="line number21 index20 alt2">
        </div>
        
        <div class="line number22 index21 alt1">
          `/**`
        </div>
        
        <div class="line number23 index22 alt2">
        </div>
        
        <div class="line number24 index23 alt1">
          `          ``*参数上面有注释`
        </div>
        
        <div class="line number25 index24 alt2">
          `*/`
        </div>
        
        <div class="line number26 index25 alt1">
          `public`  `MyCountTimer (TextView btn, ``int` `endStrRid) {`
        </div>
        
        <div class="line number27 index26 alt2">
          `super``(TIME_COUNT, ``1000``);`
        </div>
        
        <div class="line number28 index27 alt1">
          `this``.btn = btn;`
        </div>
        
        <div class="line number29 index28 alt2">
          `this``.endStrRid = endStrRid;`
        </div>
        
        <div class="line number30 index29 alt1">
          `}`
        </div>
        
        <div class="line number31 index30 alt2">
        </div>
        
        <div class="line number32 index31 alt1">
          `public` `MyCountTimer (TextView btn) {`
        </div>
        
        <div class="line number33 index32 alt2">
          `super``(TIME_COUNT, ``1000``);`
        </div>
        
        <div class="line number34 index33 alt1">
          `this``.btn = btn;`
        </div>
        
        <div class="line number35 index34 alt2">
          `this``.endStrRid = R.string.txt_getMsgCode_validate;`
        </div>
        
        <div class="line number36 index35 alt1">
          `}`
        </div>
        
        <div class="line number37 index36 alt2">
        </div>
        
        <div class="line number38 index37 alt1">
        </div>
        
        <div class="line number39 index38 alt2">
          `public` `MyCountTimer (TextView tv_varify, ``int` `normalColor, ``int` `timingColor) {`
        </div>
        
        <div class="line number40 index39 alt1">
          `this``(tv_varify);`
        </div>
        
        <div class="line number41 index40 alt2">
          `this``.normalColor = normalColor;`
        </div>
        
        <div class="line number42 index41 alt1">
          `this``.timingColor = timingColor;`
        </div>
        
        <div class="line number43 index42 alt2">
          `}`
        </div>
        
        <div class="line number44 index43 alt1">
        </div>
        
        <div class="line number45 index44 alt2">
          `// 计时完毕时触发`
        </div>
        
        <div class="line number46 index45 alt1">
          `@Override`
        </div>
        
        <div class="line number47 index46 alt2">
          `public` `void` `onFinish() {`
        </div>
        
        <div class="line number48 index47 alt1">
          `if``(normalColor &gt; ````){`
        </div>
        
        <div class="line number49 index48 alt2">
          `btn.setTextColor(normalColor);`
        </div>
        
        <div class="line number50 index49 alt1">
          `}`
        </div>
        
        <div class="line number51 index50 alt2">
          `btn.setText(endStrRid);`
        </div>
        
        <div class="line number52 index51 alt1">
          `btn.setEnabled(``true``);`
        </div>
        
        <div class="line number53 index52 alt2">
          `}`
        </div>
        
        <div class="line number54 index53 alt1">
        </div>
        
        <div class="line number55 index54 alt2">
          `// 计时过程显示`
        </div>
        
        <div class="line number56 index55 alt1">
          `@Override`
        </div>
        
        <div class="line number57 index56 alt2">
          `public` `void` `onTick(``long` `millisUntilFinished) {`
        </div>
        
        <div class="line number58 index57 alt1">
          `if``(timingColor &gt; ````){`
        </div>
        
        <div class="line number59 index58 alt2">
          `btn.setTextColor(timingColor);`
        </div>
        
        <div class="line number60 index59 alt1">
          `}`
        </div>
        
        <div class="line number61 index60 alt2">
          `btn.setEnabled(``false``);`
        </div>
        
        <div class="line number62 index61 alt1">
          `btn.setText(millisUntilFinished / ``1000` `+ ``"s"``);`
        </div>
        
        <div class="line number63 index62 alt2">
          `}`
        </div>
        
        <div class="line number64 index63 alt1">
          `}`
        </div>
      </div>
    </td>
  </tr>
</table>

 

然后在你要实现倒计时的页面用就可以了:

比如在AcvitityA中点击倒时间的按钮

Button smsBtn=findViewById(R.id…..);

MyCountTimertimeCount = new MyCountTimer(smsBtn, 0xfff30008, 0xff969696);//传入了文字颜色值
timeCount.start();

如时你不传入颜色值的话,也可以在点击按钮smsBtn的布局文件中根据按钮状态来设置颜色。

 

[?](http://www.open-open.com/code/view/1426335036826#)
<table border="0" cellspacing="0" cellpadding="0">
  <tr>
    <td class="gutter">
      <div class="line number1 index0 alt2">
        1
      </div>
      
      <div class="line number2 index1 alt1">
        2
      </div>
      
      <div class="line number3 index2 alt2">
        3
      </div>
      
      <div class="line number4 index3 alt1">
        4
      </div>
      
      <div class="line number5 index4 alt2">
        5
      </div>
      
      <div class="line number6 index5 alt1">
        6
      </div>
      
      <div class="line number7 index6 alt2">
        7
      </div>
      
      <div class="line number8 index7 alt1">
        8
      </div>
      
      <div class="line number9 index8 alt2">
        9
      </div>
      
      <div class="line number10 index9 alt1">
        10
      </div>
      
      <div class="line number11 index10 alt2">
        11
      </div>
    </td>
    
    <td class="code">
      <div class="container">
        <div class="line number1 index0 alt2">
          `&lt;``Button`
        </div>
        
        <div class="line number2 index1 alt1">
          `            ``android:id``=``"@+id/rebind_sms_btn"`
        </div>
        
        <div class="line number3 index2 alt2">
          `            ``android:layout_width``=``"120dp"`
        </div>
        
        <div class="line number4 index3 alt1">
          `            ``android:layout_height``=``"45dp"`
        </div>
        
        <div class="line number5 index4 alt2">
          `            ``android:layout_marginLeft``=``"5dp"`
        </div>
        
        <div class="line number6 index5 alt1">
          `            ``android:layout_marginRight``=``"5dp"`
        </div>
        
        <div class="line number7 index6 alt2">
          `            ``android:background``=``"@null"`
        </div>
        
        <div class="line number8 index7 alt1">
          `            ``android:gravity``=``"center"`
        </div>
        
        <div class="line number9 index8 alt2">
          `            ``android:text``=``"获取短信验证码"`
        </div>
        
        <div class="line number10 index9 alt1">
          `            ``android:textColor``=``"@color/hkb_binder_phone_text_color"`
        </div>
        
        <div class="line number11 index10 alt2">
          `            ``android:textSize``=``"16sp"` `/&gt;`
        </div>
      </div>
    </td>
  </tr>
</table>

 

文字颜色对应的xml文件:

[?](http://www.open-open.com/code/view/1426335036826#)
<table border="0" cellspacing="0" cellpadding="0">
  <tr>
    <td class="gutter">
      <div class="line number1 index0 alt2">
        1
      </div>
      
      <div class="line number2 index1 alt1">
        2
      </div>
      
      <div class="line number3 index2 alt2">
        3
      </div>
      
      <div class="line number4 index3 alt1">
        4
      </div>
      
      <div class="line number5 index4 alt2">
        5
      </div>
    </td>
    
    <td class="code">
      <div class="container">
        <div class="line number1 index0 alt2">
          `&lt;?``xml` `version``=``"1.0"` `encoding``=``"utf-8"``?&gt;`
        </div>
        
        <div class="line number2 index1 alt1">
          `&lt;``selector` `xmlns:android``=``"http://schemas.android.com/apk/res/android"``&gt;`
        </div>
        
        <div class="line number3 index2 alt2">
          `    ``&lt;``item` `android:state_enabled``=``"false"` `android:color``=``"#969696"``/&gt;`
        </div>
        
        <div class="line number4 index3 alt1">
          `    ``&lt;``item` `android:color``=``"#f30008"``/&gt;`
        </div>
        
        <div class="line number5 index4 alt2">
          `&lt;/``selector``&gt;`
        </div>
      </div>
    </td>
  </tr>
</table>



  转自:http://www.open-open.com/code/view/1426335036826

 

在逛论坛的时候,看到一个网友提问,说到了CountDownTimer这个类,从名字上面大家就可以看出来,记录下载时间。将后台线程的创建和Handler队列封装成一个方便的类调用。

查看了一下官方文档,这个类及其简单,只有四个方法,上面都涉及到了onTick,onFinsh、cancel和start。其中前面两个是抽象方法,所以要重写一下。
下面是官方给的一个小例子:

**[java]** [view plain](http://blog.csdn.net/lilu_leo/article/details/6941724#)[copy](http://blog.csdn.net/lilu_leo/article/details/6941724#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/629800)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/629800/fork)
  <div>
    <embed id="ZeroClipboardMovie_1" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_1">
    </embed>
  </div>
</div>
- <span class="keyword">new</span> CountdownTimer(<span class="number">30000</span>, <span class="number">1000</span>) {

- <span class="keyword">public</span> <span class="keyword">void</span> onTick(<span class="keyword">long</span> millisUntilFinished) {

- mTextField.setText(<span class="string">&#8220;seconds remaining: &#8220;</span> + millisUntilFinished / <span class="number">1000</span>);

- }

- <span class="keyword">public</span> <span class="keyword">void</span> onFinish() {

- mTextField.setText(<span class="string">&#8220;done!&#8221;</span>);

- }

- }.start();

直接用的那位网友的代码,自己稍微改动了一下,一个简单的小demo。

**[java]** [view plain](http://blog.csdn.net/lilu_leo/article/details/6941724#)[copy](http://blog.csdn.net/lilu_leo/article/details/6941724#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/629800)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/629800/fork)
  <div>
    <embed id="ZeroClipboardMovie_2" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_2">
    </embed>
  </div>
</div>
- <span class="keyword">package</span> cn.demo;

- 
- <span class="keyword">import</span> android.app.Activity;

- <span class="keyword">import</span> android.os.Bundle;

- <span class="keyword">import</span> android.content.Intent;

- <span class="keyword">import</span> android.os.CountDownTimer;

- <span class="keyword">import</span> android.widget.TextView;

- <span class="keyword">import</span> android.widget.Toast;

- <span class="keyword">public</span> <span class="keyword">class</span> NewActivity <span class="keyword">extends</span> Activity {

- <span class="keyword">private</span> MyCount mc;

- <span class="keyword">private</span> TextView tv;

- <span class="annotation">@Override</span>

- <span class="keyword">protected</span> <span class="keyword">void</span> onCreate(Bundle savedInstanceState) {

- <span class="comment">// TODO Auto-generated method stub</span>

- <span class="keyword">super</span>.onCreate(savedInstanceState);

- setContentView(R.layout.main);

- tv = (TextView)findViewById(R.id.show);

- mc = <span class="keyword">new</span> MyCount(<span class="number">30000</span>, <span class="number">1000</span>);

- mc.start();

- }<span class="comment">//end func</span>

- 
- <span class="comment">/*定义一个倒计时的内部类*/</span>

- <span class="keyword">class</span> MyCount <span class="keyword">extends</span> CountDownTimer {

- <span class="keyword">public</span> MyCount(<span class="keyword">long</span> millisInFuture, <span class="keyword">long</span> countDownInterval) {

- <span class="keyword">super</span>(millisInFuture, countDownInterval);

- }

- <span class="annotation">@Override</span>

- <span class="keyword">public</span> <span class="keyword">void</span> onFinish() {

- tv.setText(<span class="string">&#8220;finish&#8221;</span>);

- }

- <span class="annotation">@Override</span>

- <span class="keyword">public</span> <span class="keyword">void</span> onTick(<span class="keyword">long</span> millisUntilFinished) {

- tv.setText(<span class="string">&#8220;请等待30秒(&#8220;</span> + millisUntilFinished / <span class="number">1000</span> + <span class="string">&#8220;)&#8230;&#8221;</span>);

- Toast.makeText(NewActivity.<span class="keyword">this</span>, millisUntilFinished / <span class="number">1000</span> + <span class="string">&#8220;&#8221;</span>, Toast.LENGTH_LONG).show();<span class="comment">//toast有显示时间延迟     </span>

- }

- }

- }

主要是重写onTick和onFinsh这两个方法,onFinish()中的代码是计时器结束的时候要做的事情;onTick(Long m)中的代码是你倒计时开始时要做的事情,参数m是直到完成的时间,构造方法MyCount()中的两个参数中,前者是倒计的时间数,后者是倒计时onTick事件响应的间隔时间,都是以毫秒为单位。例如要倒计时30秒,每秒中间间隔时间是1秒,两个参数可以这样MyCount(30000,1000)。 将后台线程的创建和Handler队列封装成为了一个方便的类调用。

当你想取消的时候使用mc.cancel()方法就行了。

 

转自:http://blog.csdn.net/lilu_leo/article/details/6941724

💬 评论