自定义倒计时控件

 

自定义倒计时控件

  5483人阅读  评论(2)  收藏  举报
  分类:
 

目录(?)[+]

前言:这几天博客积的有点多,工作也是忙的够呛.


先上本篇效果图:

就是自定义一个能倒计时的TextView控件,当我们点击start run按钮时,给他传进去一个时间数字,它自己开始倒计时,不需要外部任何干预。当点击Stop run按钮时,停止倒计时。


一、自定义倒计时控件——TimerTextView

显然TimerTextView应该派生于TextView,因为他本就是显示一串Text,只是具有了自动更新的功能,这里的自动更新的实现当然只通过线程来实现了,所以要继承Runnable接口。所以它的定义应该是这样的:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public class TimerTextView extends TextView implements Runnable{  
  2.       
  3.     public TimerTextView(Context context, AttributeSet attrs) {  
  4.         super(context, attrs);  
  5.         // TODO Auto-generated constructor stub  
  6.     }  
  7.     @Override  
  8.     public void run() {  
  9.         //自动更新  
  10.           
  11.     }  
  12.   
  13. }  
首先,要给外部提供一个函数,可以给它设置要开始倒计时的数字:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. private long mday, mhour, mmin, msecond;//天,小时,分钟,秒  

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public void setTimes(long[] times) {  
  2.     mday = times[0];  
  3.     mhour = times[1];  
  4.     mmin = times[2];  
  5.     msecond = times[3];  
  6.   
  7. }  
然后要实现当前线程的开始和终止,相关实现是下面几个函数:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. private boolean run=false//是否启动了  
[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public boolean isRun() {  
  2.     return run;  
  3. }  
  4.   
  5. public void beginRun() {  
  6.     this.run = true;  
  7.     run();  
  8. }  
  9.   
  10. public void stopRun(){  
  11.     this.run = false;  
  12. }  
这里定义一个变量run来标识当前线程是否已经启动,如果没有启动,我们可以调用beginRun()来开始线程,在beginRun()函数中,调用run()开线程开始运行,在线程中,我们就要实现一秒更新一次当前数字了:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. @Override  
  2. public void run() {  
  3.     //标示已经启动  
  4.     if(run){  
  5.         ComputeTime();  
  6.   
  7.         String strTime= mday +"天:"+ mhour+"小时:"+ mmin+"分钟:"+msecond+"秒";  
  8.         this.setText(strTime);  
  9.   
  10.         postDelayed(this1000);  
  11.     }else {  
  12.         removeCallbacks(this);  
  13.     }  
  14. }  
首先判断当前线程应该具有的状态,如果还是在跑着(即run变量为true),那就计算当前应该显示的时间(ComputeTime()函数),然后设置给自己。最后利用postDelayed(this,1000),来延长1秒后再运行一次。

如果用户调用了StopRun()函数,将run变量置为了FALSE,即用户要停止线程运行,这里,我们调用removeCallbacks(this)来终止当前线程。
下面就是看看如何来计算当前要显示的时间的omputeTime()函数了:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. private void ComputeTime() {  
  2.     msecond--;  
  3.     if (msecond < 0) {  
  4.         mmin--;  
  5.         msecond = 59;  
  6.         if (mmin < 0) {  
  7.             mmin = 59;  
  8.             mhour--;  
  9.             if (mhour < 0) {  
  10.                 // 倒计时结束  
  11.                 mhour = 24;  
  12.                 mday--;  
  13.   
  14.             }  
  15.         }  
  16.   
  17.     }  
  18.   
  19. }  
理解起来应该没什么难度,秒一次减一,如果减到0,一方面重置为59,另一方面分钟要减一,当分钟减到0时,一方面分钟置为59,一方面小时减一,天的计划一样,需要注意的是,一天是24个小时哦,不是60。
OK啦,重写控件的部分就讲完了,下面列出这块的完整代码,供大家参考:
[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public class TimerTextView extends TextView implements Runnable{  
  2.       
  3.     public TimerTextView(Context context, AttributeSet attrs) {  
  4.         super(context, attrs);  
  5.         // TODO Auto-generated constructor stub  
  6.     }  
  7.   
  8.     private long mday, mhour, mmin, msecond;//天,小时,分钟,秒  
  9.     private boolean run=false//是否启动了  
  10.   
  11.     public void setTimes(long[] times) {  
  12.         mday = times[0];  
  13.         mhour = times[1];  
  14.         mmin = times[2];  
  15.         msecond = times[3];  
  16.   
  17.     }  
  18.   
  19.     /** 
  20.      * 倒计时计算 
  21.      */  
  22.     private void ComputeTime() {  
  23.         msecond--;  
  24.         if (msecond < 0) {  
  25.             mmin--;  
  26.             msecond = 59;  
  27.             if (mmin < 0) {  
  28.                 mmin = 59;  
  29.                 mhour--;  
  30.                 if (mhour < 0) {  
  31.                     // 倒计时结束,一天有24个小时  
  32.                     mhour = 23;  
  33.                     mday--;  
  34.       
  35.                 }  
  36.             }  
  37.       
  38.         }  
  39.       
  40.     }  
  41.   
  42.     public boolean isRun() {  
  43.         return run;  
  44.     }  
  45.   
  46.     public void beginRun() {  
  47.         this.run = true;  
  48.         run();  
  49.     }  
  50.       
  51.     public void stopRun(){  
  52.         this.run = false;  
  53.     }  
  54.       
  55.   
  56.     @Override  
  57.     public void run() {  
  58.         //标示已经启动  
  59.         if(run){  
  60.             ComputeTime();  
  61.   
  62.             String strTime= mday +"天:"+ mhour+"小时:"+ mmin+"分钟:"+msecond+"秒";  
  63.             this.setText(strTime);  
  64.   
  65.             postDelayed(this1000);  
  66.         }else {  
  67.             removeCallbacks(this);  
  68.         }  
  69.     }  
  70.   
  71. }  

二、控件使用

下面我们就在MainActivity中使用一下,先看看MainActivity的布局(activity_main.xml)

从最开头的演示中也可以看出,使用的是垂直布局,两个BTN,一个倒计时TextView

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:orientation="vertical"  
  6.     tools:context="com.example.trytimerview.MainActivity" >  
  7.       
  8.     <Button android:id="@+id/main_start_btn"  
  9.         android:layout_width="match_parent"  
  10.         android:layout_height="wrap_content"  
  11.         android:text="start run"/>  
  12.       
  13.     <Button android:id="@+id/main_stop_btn"  
  14.         android:layout_width="match_parent"  
  15.         android:layout_height="wrap_content"  
  16.         android:text="stop run"/>  
  17.       
  18.   
  19.     <com.example.trytimerview.TimerTextView   
  20.         android:id="@+id/timer_text_view"  
  21.         android:layout_width="fill_parent"  
  22.         android:layout_height="wrap_content"  
  23.         android:textSize="18sp"  
  24.         android:textColor="#ff0000"  
  25.         android:gravity="center_horizontal"  
  26.         android:text="倒计时"  
  27.         />  
  28.   
  29. </LinearLayout>  
然后是在MainActivity中,先列出整体的代码,然后再细讲:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public class MainActivity extends Activity {  
  2.   
  3.     @Override  
  4.     protected void onCreate(Bundle savedInstanceState) {  
  5.         super.onCreate(savedInstanceState);  
  6.         setContentView(R.layout.activity_main);  
  7.         //初始化倒计时控件  
  8.         final TimerTextView timerTextView = (TimerTextView)findViewById(R.id.timer_text_view);  
  9.         long[] times = {0,10,5,30};  
  10.         timerTextView.setTimes(times);  
  11.           
  12.           
  13.         Button startBtn =  (Button)findViewById(R.id.main_start_btn);  
  14.         Button stopBtn  =  (Button)findViewById(R.id.main_stop_btn);  
  15.         //开始倒计时  
  16.         startBtn.setOnClickListener(new View.OnClickListener() {  
  17.               
  18.             @Override  
  19.             public void onClick(View v) {  
  20.                 // TODO Auto-generated method stub  
  21.                 if(!timerTextView.isRun()){  
  22.                     timerTextView.beginRun();  
  23.                 }  
  24.             }  
  25.         });  
  26.           
  27.         //停止倒计时  
  28.         stopBtn.setOnClickListener(new View.OnClickListener() {  
  29.               
  30.             @Override  
  31.             public void onClick(View v) {  
  32.                 // TODO Auto-generated method stub  
  33.                 if(timerTextView.isRun()){  
  34.                     timerTextView.stopRun();  
  35.                 }  
  36.             }  
  37.         });  
  38.   
  39.     }  
  40.   
  41. }  
这里首先是,初始化TimerTextView控件:

初始化为从10个小时,5分钟,30秒开始倒计时

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. final TimerTextView timerTextView = (TimerTextView)findViewById(R.id.timer_text_view);  
  2. long[] times = {0,10,5,30};  
  3. timerTextView.setTimes(times);  
然后当用户点击StartRun按钮时,先判断当前是否在运行,如果没在运行,就让它开始跑起来:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. startBtn.setOnClickListener(new View.OnClickListener() {  
  2.       
  3.     @Override  
  4.     public void onClick(View v) {  
  5.         // TODO Auto-generated method stub  
  6.         if(!timerTextView.isRun()){  
  7.             timerTextView.beginRun();  
  8.         }  
  9.     }  
  10. });  
当用户点击Stop Run按钮时,停止运行:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. stopBtn.setOnClickListener(new View.OnClickListener() {  
  2.       
  3.     @Override  
  4.     public void onClick(View v) {  
  5.         // TODO Auto-generated method stub  
  6.         if(timerTextView.isRun()){  
  7.             timerTextView.stopRun();  
  8.         }  
  9.     }  
  10. });  


OK啦,这篇比较简单,代码量也比较小,就不再多说了。


如果这篇文章有帮到你,记得关注哦

源码下载地址:http://download.csdn.net/detail/harvic880925/8271087

请大家尊重原创者版权,转载请标时出处:http://blog.csdn.net/harvic880925/article/details/41977569  谢谢。

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 扫一扫,分享海报

参与评论 您还未登录,请先 登录 后发表或查看评论
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值