自定义倒计时控件

来源:互联网 发布:上海php培训哪家好 编辑:程序博客网 时间:2024/05/17 23:32

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


先上本篇效果图:

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


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

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

public class TimerTextView extends TextView implements Runnable{public TimerTextView(Context context, AttributeSet attrs) {super(context, attrs);// TODO Auto-generated constructor stub}    @Override    public void run() {        //自动更新        }}
首先,要给外部提供一个函数,可以给它设置要开始倒计时的数字:

private long mday, mhour, mmin, msecond;//天,小时,分钟,秒

public void setTimes(long[] times) {    mday = times[0];    mhour = times[1];    mmin = times[2];    msecond = times[3];}
然后要实现当前线程的开始和终止,相关实现是下面几个函数:

private boolean run=false; //是否启动了
public boolean isRun() {    return run;}public void beginRun() {    this.run = true;    run();}public void stopRun(){this.run = false;}
这里定义一个变量run来标识当前线程是否已经启动,如果没有启动,我们可以调用beginRun()来开始线程,在beginRun()函数中,调用run()开线程开始运行,在线程中,我们就要实现一秒更新一次当前数字了:

@Overridepublic void run() {    //标示已经启动    if(run){    ComputeTime();        String strTime= mday +"天:"+ mhour+"小时:"+ mmin+"分钟:"+msecond+"秒";        this.setText(strTime);        postDelayed(this, 1000);    }else {    removeCallbacks(this);    }}
首先判断当前线程应该具有的状态,如果还是在跑着(即run变量为true),那就计算当前应该显示的时间(ComputeTime()函数),然后设置给自己。最后利用postDelayed(this,1000),来延长1秒后再运行一次。

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

private void ComputeTime() {    msecond--;    if (msecond < 0) {        mmin--;        msecond = 59;        if (mmin < 0) {            mmin = 59;            mhour--;            if (mhour < 0) {                // 倒计时结束                mhour = 24;                mday--;            }        }    }}
理解起来应该没什么难度,秒一次减一,如果减到0,一方面重置为59,另一方面分钟要减一,当分钟减到0时,一方面分钟置为59,一方面小时减一,天的计划一样,需要注意的是,一天是24个小时哦,不是60。
OK啦,重写控件的部分就讲完了,下面列出这块的完整代码,供大家参考:
public class TimerTextView extends TextView implements Runnable{public TimerTextView(Context context, AttributeSet attrs) {super(context, attrs);// TODO Auto-generated constructor stub}    private long mday, mhour, mmin, msecond;//天,小时,分钟,秒    private boolean run=false; //是否启动了    public void setTimes(long[] times) {        mday = times[0];        mhour = times[1];        mmin = times[2];        msecond = times[3];    }    /**     * 倒计时计算     */private void ComputeTime() {    msecond--;    if (msecond < 0) {        mmin--;        msecond = 59;        if (mmin < 0) {            mmin = 59;            mhour--;            if (mhour < 0) {                // 倒计时结束,一天有24个小时                mhour = 23;                mday--;            }        }    }}    public boolean isRun() {        return run;    }    public void beginRun() {        this.run = true;        run();    }        public void stopRun(){    this.run = false;    }        @Override    public void run() {        //标示已经启动        if(run){        ComputeTime();            String strTime= mday +"天:"+ mhour+"小时:"+ mmin+"分钟:"+msecond+"秒";            this.setText(strTime);            postDelayed(this, 1000);        }else {        removeCallbacks(this);        }    }}

二、控件使用

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

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

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    tools:context="com.example.trytimerview.MainActivity" >        <Button android:id="@+id/main_start_btn"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="start run"/>        <Button android:id="@+id/main_stop_btn"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="stop run"/>        <com.example.trytimerview.TimerTextView         android:id="@+id/timer_text_view"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:textSize="18sp"        android:textColor="#ff0000"        android:gravity="center_horizontal"        android:text="倒计时"        /></LinearLayout>
然后是在MainActivity中,先列出整体的代码,然后再细讲:

public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//初始化倒计时控件final TimerTextView timerTextView = (TimerTextView)findViewById(R.id.timer_text_view);long[] times = {0,10,5,30};timerTextView.setTimes(times);Button startBtn =  (Button)findViewById(R.id.main_start_btn);Button stopBtn  =  (Button)findViewById(R.id.main_stop_btn);//开始倒计时startBtn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubif(!timerTextView.isRun()){timerTextView.beginRun();}}});//停止倒计时stopBtn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubif(timerTextView.isRun()){timerTextView.stopRun();}}});}}
这里首先是,初始化TimerTextView控件:

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

final TimerTextView timerTextView = (TimerTextView)findViewById(R.id.timer_text_view);long[] times = {0,10,5,30};timerTextView.setTimes(times);
然后当用户点击StartRun按钮时,先判断当前是否在运行,如果没在运行,就让它开始跑起来:

startBtn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubif(!timerTextView.isRun()){timerTextView.beginRun();}}});
当用户点击Stop Run按钮时,停止运行:

stopBtn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubif(timerTextView.isRun()){timerTextView.stopRun();}}});


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


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

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

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



9 0