一、使用api提供的类进行操作

Android提供了CountDownTimer来让我们进行倒计时,可以让我们很方便的进行倒计时的操作。使用方式也很简单,下面直接贴代码就好了:

package com.kale.duitanglib.time;

import com.kale.lib.activity.KaleBaseActivity;

import android.os.Bundle;
import android.os.CountDownTimer;
import android.util.Log; /**
* @author Jack Tony
* @brief 官方提供的CountDownTimer来实现
* 在activity退出后还会持续计时,所以结束时需要判断当前activity是否在前台
* @date 2015/4/26
*/
public class SimpleCountDownTimerActivity extends KaleBaseActivity { @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
startCountDownTime(6); } private void startCountDownTime(long time) {
/**
* 最简单的倒计时类,实现了官方的CountDownTimer类(没有特殊要求的话可以使用)
* 即使退出activity,倒计时还能进行,因为是创建了后台的线程。
* 有onTick,onFinsh、cancel和start方法
*/
CountDownTimer timer = new CountDownTimer(time * 1000, 1000) {
@Override
public void onTick(long millisUntilFinished) {
//每隔countDownInterval秒会回调一次onTick()方法
Log.d(TAG, "onTick " + millisUntilFinished / 1000);
} @Override
public void onFinish() {
Log.d(TAG, "onFinish -- 倒计时结束");
}
};
timer.start();// 开始计时
//timer.cancel(); // 取消
}
}

需要注意的点就是如果你是需要从5秒开始倒计时,每隔一秒进行一次onTick回调,那么你在构造类的时候需要传入5*1000和1000.此外开始倒计时后会开启一个后台线程,这样即使是你的activity被关掉,倒计时还是会执行的,所以你需要防范这个问题。解决思路是在activitydestroy的时候cancel掉它。或者是在倒计时结束时要更新UI的时候进行ui元素是否可见(存在)的判断。

二、让我们自定义一个倒计时类吧

如果我们想进行更多的功能,比如暂停,回复等等就需要自定义一个倒计时类了,就像下面这样:

package com.kale.lib.time;

import android.os.Handler;
import android.os.Message; /**
* Jack Tony
* 自定义的倒计时类,没有用官方提供的CountDownTimer来实现
* 有暂停等方法,灵活性强。在activity退出后还会持续计时,所以结束时需要判断当前activity是否在前台
* @date 2015/4/24
*/ public abstract class AdvancedCountdownTimer { private final long mCountdownInterval; private long mTotalTime; private long mRemainTime;
/**
*
* @param millisInFuture
* 表示以毫秒为单位 倒计时的总数
*
* 例如 millisInFuture=1000 表示1秒
*
* @param countDownInterval
* 表示 间隔 多少微秒 调用一次 onTick 方法
*
* 例如: countDownInterval =1000 ; 表示每1000毫秒调用一次onTick()
*
*/
public AdvancedCountdownTimer(long millisInFuture, long countDownInterval) {
mTotalTime = millisInFuture;
mCountdownInterval = countDownInterval;
mRemainTime = millisInFuture;
} public final void seek(int value) {
synchronized (AdvancedCountdownTimer.this) {
mRemainTime = ((100 - value) * mTotalTime) / 100;
}
} public final void cancel() {
mHandler.removeMessages(MSG_RUN);
mHandler.removeMessages(MSG_PAUSE);
} public final void resume() {
mHandler.removeMessages(MSG_PAUSE);
mHandler.sendMessageAtFrontOfQueue(mHandler.obtainMessage(MSG_RUN));
} public final void pause() {
mHandler.removeMessages(MSG_RUN);
mHandler.sendMessageAtFrontOfQueue(mHandler.obtainMessage(MSG_PAUSE));
} public synchronized final AdvancedCountdownTimer start() {
if (mRemainTime <= 0) {
onFinish();
return this;
}
mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_RUN),
mCountdownInterval);
return this;
} public abstract void onTick(long millisUntilFinished, int percent); public abstract void onFinish(); private static final int MSG_RUN = 1; private static final int MSG_PAUSE = 2; private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
synchronized (AdvancedCountdownTimer.this) {
if (msg.what == MSG_RUN) {
mRemainTime = mRemainTime - mCountdownInterval;
if (mRemainTime <= 0) {
onFinish();
} else if (mRemainTime < mCountdownInterval) {
sendMessageDelayed(obtainMessage(MSG_RUN), mRemainTime);
} else {
onTick(mRemainTime, new Long(100
* (mTotalTime - mRemainTime) / mTotalTime)
.intValue()); sendMessageDelayed(obtainMessage(MSG_RUN),
mCountdownInterval);
}
} else if (msg.what == MSG_PAUSE) {
}
}
}
}; }

用法和上面完全一样,直接看代码:

package com.kale.duitanglib.time;

import com.kale.lib.activity.KaleBaseActivity;

import android.os.Bundle;
import android.util.Log; /**
* @author Jack Tony
* @brief
* @date 2015/4/26
*/
public class AdvancedCountdownTimerActivity extends KaleBaseActivity{ @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 8秒倒计时
com.kale.lib.time.AdvancedCountdownTimer countdownTimer = new com.kale.lib.time.AdvancedCountdownTimer(8 * 1000, 1000) {
@Override
public void onTick(long millisUntilFinished, int percent) {
//每隔countDownInterval秒会回调一次onTick()方法
Log.d(TAG,"onTick " + millisUntilFinished / 1000);
} @Override
public void onFinish() {
// 倒计时结束
Log.d(TAG, "onFinish -- 倒计时结束");
}
};
countdownTimer.start();
}
}

用这个类的时候同样需要注意,界面是否被关闭的问题。如果你的界面关闭了,而倒计时仍旧在进行的话,这时再更新UI可能会出现问题。下面贴出一个activity的测试代码:

package com.kale.countdowntimer;

import com.kale.lib.activity.KaleBaseActivity;

import android.os.CountDownTimer;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView; /**
* @author Jack Tony
* @date 2015/5/7
*/
public class MainActivity extends KaleBaseActivity { private Button normalCountDownTimeButton; private Button customCountDownTimeButton; private TextView timeTextView; @Override
protected int getContentViewId() {
return R.layout.activity_main;
} @Override
protected void findViews() {
normalCountDownTimeButton = getView(R.id.normalCountDownTime_button);
customCountDownTimeButton = getView(R.id.custom_CountDownTime_button);
timeTextView = getView(R.id.time_textView);
} @Override
protected void setViews() {
normalCountDownTimeButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startNormalCountDownTime(5); }
});
customCountDownTimeButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startCustomCountDownTime(5);
}
});
} private void startNormalCountDownTime(long time) {
/**
* 最简单的倒计时类,实现了官方的CountDownTimer类(没有特殊要求的话可以使用)
* 即使退出activity,倒计时还能进行,因为是创建了后台的线程。
* 有onTick,onFinsh、cancel和start方法
*/
CountDownTimer timer = new CountDownTimer(time * 1000, 1000) {
@Override
public void onTick(long millisUntilFinished) {
Log.d(TAG, "onTick " + millisUntilFinished / 1000);
timeTextView.setText("还剩" + millisUntilFinished / 1000 + "秒");
} @Override
public void onFinish() {
Log.d(TAG, "onFinish -- 倒计时结束");
timeTextView.setText("结束");
}
};
timer.start();
//timer.cancel();
} private void startCustomCountDownTime(long time) {
com.kale.lib.time.AdvancedCountdownTimer countdownTimer = new com.kale.lib.time.AdvancedCountdownTimer(time * 1000, 1000) {
@Override
public void onTick(long millisUntilFinished, int percent) {
Log.d(TAG, "onTick " + millisUntilFinished / 1000);
timeTextView.setText("还剩" + millisUntilFinished / 1000 + "秒");
} @Override
public void onFinish() {
Log.d(TAG, "onFinish -- 倒计时结束");
timeTextView.setText("结束");
}
};
countdownTimer.start();
} }

源码下载:http://download.csdn.net/detail/shark0017/8671631

Android中方便好用的倒计时类的更多相关文章

  1. android中与SQLite数据库相关的类

    为什么要在应用程序中使用数据库?数据库最主要的用途就是作为数据的存储容器,另外,由于可以很方便的将应用程序中的数据结构(比如C语言中的结构体)转化成数据库的表,这样我们就可以通过操作数据库来替代写一堆 ...

  2. Android中内容观察者的使用---- ContentObserver类详解 (转)

    前言: 工作中,需要开启一个线程大量的查询某个数据库值发送了变化,导致的开销很大,后来在老大的指点下,利用了 ContentObserver完美的解决了该问题,感到很兴奋,做完之后自己也对Conten ...

  3. Android中蓝牙的基本使用----BluetoothAdapter类简介

    天气逐渐热了,自己也越来越懒了,虽然看着了很多东西,解决了很多问题,有些收获却不想写着.主要有一下两方面原因: 第一.以前写的一些关于Android知识的Blog,都是在学习过程中发现网络上没有相关知 ...

  4. Android中内容观察者的使用---- ContentObserver类详解

    详解:http://blog.csdn.net/qinjuning/article/details/7047607

  5. [转]Android中Application类的用法

    原文链接:http://www.cnblogs.com/renqingping/archive/2012/10/24/Application.html Application类 Application ...

  6. 【转】Android中Application类用法

    转自:http://www.cnblogs.com/renqingping/archive/2012/10/24/Application.html Application类 Application和A ...

  7. Android(java)学习笔记120:Android中的Application类用法

    1.简介 如果想在整个应用中使用全局变量,在java中一般是使用静态变量,public类型:而在android中如果使用这样的全局变量就不符合Android的框架架构,但是可以使用一种更优雅的方式就是 ...

  8. Android中Application类用法

    Application类 Application和Activity,Service一样是Android框架的一个系统组件,当Android程序启动时系统会创建一个Application对象,用来存储系 ...

  9. Android(java)学习笔记61:Android中的 Application类用法

    1. 简介 如果想在整个应用中使用全局变量,在java中一般是使用静态变量,public类型:而在android中如果使用这样的全局变量就不符合Android的框架架构,但是可以使用一种更优雅的方式就 ...

随机推荐

  1. struts2 using kindeditor upload pictures (including jmagic compressed images)

    Project uses a kindeditor3.4 UploadContentImgAction @SuppressWarnings("serial") @ParentPac ...

  2. 解决Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future:

    php 5个版本,5.2.5.3.5.4.5.5,怕跟不上时代,新的服务器直接上5.5,但是程序出现如下错误:Deprecated: mysql_connect(): The mysql extens ...

  3. Unity 摄像机Clear Flags和Culling Mask属性用途详解

    原文地址:http://blog.csdn.net/tanmengwen/article/details/8798231 1.简述两个属性 1.1 Clear Flags 清除标记 每个相机在渲染时会 ...

  4. python异常处理(基础)

    之前在学习python的时候有整理过python异常处理的文章,不够简单也不够完整,所以决定再整理一篇,算做补充. http://www.cnblogs.com/fnng/archive/2013/0 ...

  5. iOS-微信-分享

    一.微信原生的分享--准备工作. 1. 需要申请微信AppId. 2. 导入系统架包. SDK文件包括 libWeChatSDK.a,WXApi.h,WXApiObject.h,WechatAuthS ...

  6. wcf服务返回json

    private static void CreateErrorReply(OperationContext operationContext, string key, HttpStatusCode s ...

  7. UWP开发入门(十四)—— UserControl中Adaptive UI的小技巧

    本篇我们通过绘制一个非常简单的UserControl控件,来分享一下对Adaptive UI的理解及一些图形绘制的技巧. 现在流行的APP都少不了精致的用户头像,首先假设我们需要绘制如下的图形作为默认 ...

  8. IOS开发UI基础UISegment属性

    UISegment属性 1.segmentedControlStyle设置segment的显示样式.typedef NS_ENUM(NSInteger, UISegmentedControlStyle ...

  9. Hibernate中延迟加载和缓存

    什么是延迟加载? 延迟加载是指当应用程序想要从数据库获取对象时(在没有设置lazy属性值为false),Hibernate只是从数据库获取符合条件的对象的OId从而生成代理对象,并没有加载出对象 访问 ...

  10. mysqlbinlog -v --base64-output 与不加的区别

    加-v与加-vv的区别: 加--base64-output=DECODE-ROWS与不加的区别: