android基础之倒计时

版权声明:本文为博主原创文章,遵循 CC 4.0 BY 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/generallizhong/article/details/49273499

一、自定义倒计时控件——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()开线程开始运行,在线程中,我们就要实现一秒更新一次当前数字了:

@Override  
public 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 {  
  
    @Override  
    protected 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() {  
              
            @Override  
            public void onClick(View v) {  
                // TODO Auto-generated method stub  
                if(!timerTextView.isRun()){  
                    timerTextView.beginRun();  
                }  
            }  
        });  
          
        //停止倒计时  
        stopBtn.setOnClickListener(new View.OnClickListener() {  
              
            @Override  
            public void onClick(View v) {  
                // TODO Auto-generated method stub  
                if(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() {  
      
    @Override  
    public void onClick(View v) {  
        // TODO Auto-generated method stub  
        if(!timerTextView.isRun()){  
            timerTextView.beginRun();  
        }  
    }  
});  

当用户点击Stop Run按钮时,停止运行:

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

结束,代码逻辑比较简单

猜你喜欢

转载自blog.csdn.net/generallizhong/article/details/49273499