android 倒计时控件

  • Post author:
  • Post category:其他





自定义倒计时控件



分类:

5、andriod开发




812人阅读



评论

(0)



收藏




举报


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


先上本篇效果图:

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





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

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


  1. public


    class

    TimerTextView

    extends

    TextView

    implements

    Runnable{

  2. public

    TimerTextView(Context context, AttributeSet attrs) {

  3. super

    (context, attrs);

  4. // TODO Auto-generated constructor stub
  5. }

  6. @Override

  7. public


    void

    run() {

  8. //自动更新
  9. }
  10. }
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() {
        //自动更新
    	
    }

}

首先,要给外部提供一个函数,可以给它设置要开始倒计时的数字:


  1. private


    long

    mday, mhour, mmin, msecond;

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


  1. public


    void

    setTimes(

    long

    [] times) {
  2. mday = times[

    0

    ];
  3. mhour = times[

    1

    ];
  4. mmin = times[

    2

    ];
  5. msecond = times[

    3

    ];
  6. }
public void setTimes(long[] times) {
    mday = times[0];
    mhour = times[1];
    mmin = times[2];
    msecond = times[3];

}

然后要实现当前线程的开始和终止,相关实现是下面几个函数:


  1. private


    boolean

    run=

    false

    ;

    //是否启动了
private boolean run=false; //是否启动了

  1. public


    boolean

    isRun() {

  2. return

    run;
  3. }

  4. public


    void

    beginRun() {

  5. this

    .run =

    true

    ;
  6. run();
  7. }

  8. public


    void

    stopRun(){

  9. this

    .run =

    false

    ;
  10. }
public boolean isRun() {
    return run;
}

public void beginRun() {
    this.run = true;
    run();
}

public void stopRun(){
	this.run = false;
}

这里定义一个变量run来标识当前线程是否已经启动,如果没有启动,我们可以调用beginRun()来开始线程,在beginRun()函数中,调用run()开线程开始运行,在线程中,我们就要实现一秒更新一次当前数字了:


  1. @Override

  2. public


    void

    run() {

  3. //标示已经启动

  4. if

    (run){
  5. ComputeTime();
  6. String strTime= mday +

    “天:”

    + mhour+

    “小时:”

    + mmin+

    “分钟:”

    +msecond+

    “秒”

    ;

  7. this

    .setText(strTime);
  8. postDelayed(

    this

    ,

    1000

    );
  9. }

    else

    {
  10. removeCallbacks(

    this

    );
  11. }
  12. }
@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()函数了:


  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. }
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啦,重写控件的部分就讲完了,下面列出这块的完整代码,供大家参考:


  1. public


    class

    TimerTextView

    extends

    TextView

    implements

    Runnable{

  2. public

    TimerTextView(Context context, AttributeSet attrs) {

  3. super

    (context, attrs);

  4. // TODO Auto-generated constructor stub
  5. }

  6. private


    long

    mday, mhour, mmin, msecond;

    //天,小时,分钟,秒

  7. private


    boolean

    run=

    false

    ;

    //是否启动了

  8. public


    void

    setTimes(

    long

    [] times) {
  9. mday = times[

    0

    ];
  10. mhour = times[

    1

    ];
  11. mmin = times[

    2

    ];
  12. msecond = times[

    3

    ];
  13. }

  14. /**

  15. * 倒计时计算

  16. */

  17. private


    void

    ComputeTime() {
  18. msecond–;

  19. if

    (msecond <

    0

    ) {
  20. mmin–;
  21. msecond =

    59

    ;

  22. if

    (mmin <

    0

    ) {
  23. mmin =

    59

    ;
  24. mhour–;

  25. if

    (mhour <

    0

    ) {

  26. // 倒计时结束,一天有24个小时
  27. mhour =

    23

    ;
  28. mday–;
  29. }
  30. }
  31. }
  32. }

  33. public


    boolean

    isRun() {

  34. return

    run;
  35. }

  36. public


    void

    beginRun() {

  37. this

    .run =

    true

    ;
  38. run();
  39. }

  40. public


    void

    stopRun(){

  41. this

    .run =

    false

    ;
  42. }

  43. @Override

  44. public


    void

    run() {

  45. //标示已经启动

  46. if

    (run){
  47. ComputeTime();
  48. String strTime= mday +

    “天:”

    + mhour+

    “小时:”

    + mmin+

    “分钟:”

    +msecond+

    “秒”

    ;

  49. this

    .setText(strTime);
  50. postDelayed(

    this

    ,

    1000

    );
  51. }

    else

    {
  52. removeCallbacks(

    this

    );
  53. }
  54. }
  55. }
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


  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. <


    Button


    android:id

    =

    “@+id/main_start_btn”

  8. android:layout_width

    =

    “match_parent”

  9. android:layout_height

    =

    “wrap_content”

  10. android:text

    =

    “start run”


    />

  11. <


    Button


    android:id

    =

    “@+id/main_stop_btn”

  12. android:layout_width

    =

    “match_parent”

  13. android:layout_height

    =

    “wrap_content”

  14. android:text

    =

    “stop run”


    />

  15. <


    com.example.trytimerview.TimerTextView

  16. android:id

    =

    “@+id/timer_text_view”

  17. android:layout_width

    =

    “fill_parent”

  18. android:layout_height

    =

    “wrap_content”

  19. android:textSize

    =

    “18sp”

  20. android:textColor

    =

    “#ff0000”

  21. android:gravity

    =

    “center_horizontal”

  22. android:text

    =

    “倒计时”

  23. />

  24. </


    LinearLayout


    >
<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中,先列出整体的代码,然后再细讲:


  1. public


    class

    MainActivity

    extends

    Activity {

  2. @Override

  3. protected


    void

    onCreate(Bundle savedInstanceState) {

  4. super

    .onCreate(savedInstanceState);
  5. setContentView(R.layout.activity_main);

  6. //初始化倒计时控件

  7. final

    TimerTextView timerTextView = (TimerTextView)findViewById(R.id.timer_text_view);

  8. long

    [] times = {


    0

    ,

    10

    ,

    5

    ,

    30

    };
  9. timerTextView.setTimes(times);
  10. Button startBtn =  (Button)findViewById(R.id.main_start_btn);
  11. Button stopBtn  =  (Button)findViewById(R.id.main_stop_btn);

  12. //开始倒计时
  13. startBtn.setOnClickListener(

    new

    View.OnClickListener() {

  14. @Override

  15. public


    void

    onClick(View v) {

  16. // TODO Auto-generated method stub

  17. if

    (!timerTextView.isRun()){
  18. timerTextView.beginRun();
  19. }
  20. }
  21. });

  22. //停止倒计时
  23. stopBtn.setOnClickListener(

    new

    View.OnClickListener() {

  24. @Override

  25. public


    void

    onClick(View v) {

  26. // TODO Auto-generated method stub

  27. if

    (timerTextView.isRun()){
  28. timerTextView.stopRun();
  29. }
  30. }
  31. });
  32. }
  33. }
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秒开始倒计时


  1. final

    TimerTextView timerTextView = (TimerTextView)findViewById(R.id.timer_text_view);

  2. long

    [] times = {


    0

    ,

    10

    ,

    5

    ,

    30

    };
  3. timerTextView.setTimes(times);
final TimerTextView timerTextView = (TimerTextView)findViewById(R.id.timer_text_view);
long[] times = {0,10,5,30};
timerTextView.setTimes(times);

然后当用户点击StartRun按钮时,先判断当前是否在运行,如果没在运行,就让它开始跑起来:

  1. startBtn.setOnClickListener(

    new

    View.OnClickListener() {

  2. @Override

  3. public


    void

    onClick(View v) {

  4. // TODO Auto-generated method stub

  5. if

    (!timerTextView.isRun()){
  6. timerTextView.beginRun();
  7. }
  8. }
  9. });
startBtn.setOnClickListener(new View.OnClickListener() {
	
	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		if(!timerTextView.isRun()){
			timerTextView.beginRun();
		}
	}
});

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

  1. stopBtn.setOnClickListener(

    new

    View.OnClickListener() {

  2. @Override

  3. public


    void

    onClick(View v) {

  4. // TODO Auto-generated method stub

  5. if

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

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



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



源码下载地址:

http://download.csdn.net/detail/harvic880925/8271087




请大家尊重原创者版权,转载请标时出处:

http://blog.csdn.net/harvic880925/article/details/41977569

谢谢。