这里使用了两种方法去实现倒计时功能,第一种相对于第二种要复杂一些,第一种算是提供一些对Chronometer的拓展思路吧
一、使用Chronometer(计时器)去实现倒计时功能
建一个CountDown类:
继承Chronometer后,在Chronometer的基础上做倒计时器
package com.example.androidviewdemo;
import java.text.SimpleDateFormat;
import java.util.Date;
import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.Chronometer;
/**
* @author Squid
*
*/
public class CountDown extends Chronometer{
private long time;
private long nextTime;
private OnTimeCompleteListener clistener;
private SimpleDateFormat format; //java中设置时间格式
@SuppressLint("SimpleDateFormat")
public CountDown(Context context, AttributeSet attrs) {
super(context, attrs);
format=new SimpleDateFormat("mm:ss");//时间格式为 分:秒
this.setOnChronometerTickListener(listener); //调用Chronometer中的监听器
}
/*
*
* 设置时间格式
*/
@SuppressLint("SimpleDateFormat")
public void setTimeFormat(String pattern){
format=new SimpleDateFormat(pattern);
}
public void setOnTimeCompleteListener(OnTimeCompleteListener l) {
clistener=l;
}
//Chronometer中的监听器,用于监视时间的改变
OnChronometerTickListener listener=new OnChronometerTickListener() {
//此方法中写关于计时器的判断逻辑
@Override
public void onChronometerTick(Chronometer chronometer) {
if (nextTime<=0) {//当倒计时为0或小于0时
if (nextTime==0) {
CountDown.this.stop();//倒计时时间为0时,倒计时停止
if (null!=clistener) {
clistener.onTimeComplete();
}
}
nextTime=0;//如时间已经小于0,则将倒计时时间停留在0
updateTimeNext();//更新时间
return;
}
nextTime--;//当倒计时还没有完成时,继续倒计时
updateTimeNext();
}
};
/*
* 初始化时间
*
*/
public void initTime(long _time_s){
time=nextTime=_time_s;
updateTimeNext();
}
private void updateTimeNext() {
// TODO Auto-generated method stub
this.setText(format.format(new Date(nextTime*1000)));//设置文本框中时间的显示
}
/*
* 重启
*/
public void reStart(long _time_s){
if (_time_s==-1) {
nextTime=time;
}else{
time=nextTime=_time_s;
}
this.start();
}
public void reStart(){
reStart(-1);
}
/*
* 继续计时
*/
public void onResume(){
this.start();
}
/*
* 暂停计时
*/
public void onPause(){
this.stop();
}
interface OnTimeCompleteListener{
void onTimeComplete();
}
}
使用这个类
package com.example.androidviewdemo;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.os.SystemClock;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.Chronometer;
import android.widget.Toast;
public class ChronometerActivity extends AppCompatActivity {
private CountDown countDown;
private int initTime=120;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chronometer);
countDown= findViewById(R.id.cd);
countDown.initTime(initTime);
countDown.setOnTimeCompleteListener(new CountDown.OnTimeCompleteListener(){
@Override
public void onTimeComplete() {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(), "倒计时结束", Toast.LENGTH_LONG).show();
}
});
}
public void btnClick(View view){
int id=view.getId();
switch (id) {
case R.id.button1:
countDown.reStart();
break;
case R.id.button2:
countDown.onPause();
break;
case R.id.button3:
countDown.onResume();//恢复
break;
case R.id.button4:
countDown.stop();
countDown.initTime(initTime);
break;
default:
break;
}
}
}
布局代码:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ChronometerActivity">
<LinearLayout
android:id="@+id/ll"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.example.androidviewdemo.CountDown
android:id="@+id/cd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:textSize="60dp"/>
<Button
android:id="@+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="22dip"
android:onClick="btnClick"
android:text="开始" />
<Button
android:id="@+id/button2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dip"
android:onClick="btnClick"
android:text="暂停" />
<Button
android:id="@+id/button3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dip"
android:onClick="btnClick"
android:text="恢复" />
<Button
android:id="@+id/button4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dip"
android:onClick="btnClick"
android:text="重置" />
</LinearLayout>
</RelativeLayout>
二、使用CountDownTimer实现倒计时功能
private Button btnCaptcha;//一个倒计时按钮
CountTimer countTimer = new CountTimer(10000, 1000);//实现CountTimer对象,并设置倒计时长为10s,倒计时的间距为1s
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnCaptcha = findViewById(R.id.btn_captcha);
//countTimer.start();//如果要到达这个界面就直接开始计时,则可以在这里开始计时
btnCaptcha.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
countTimer.start();//点击倒计时按钮之后才开始计时
}
});
}
//建一个内部类去继承CountDownTimer 类
public class CountTimer extends CountDownTimer {
public CountTimer(long millisInFuture, long countDownInterval) {//构造方法。参数:倒计时的时长,倒计时的时间间隔(1s)
super(millisInFuture, countDownInterval);
}
//计时过程中,即倒计时完成前
@Override
public void onTick(long millisUntilFinished) {
int time = (int)(Math.round((double)millisUntilFinished/1000)-1);//将毫秒转换成秒
btnCaptcha.setText(String.valueOf(time)+"s后重新发送");//设置倒计时按钮的剩余时间
btnCaptcha.setClickable(false);//设置倒计时按钮不可按
btnCaptcha.setBackgroundColor(Color.parseColor("#c7c7c7"));//设置倒计时按钮上的背景颜色
btnCaptcha.setTextColor(ContextCompat.getColor(MainActivity.this,android.R.color.black));
btnCaptcha.setTextSize(16);
}
//倒计时完成后
@Override
public void onFinish() {
Log.d("MainActivity","倒计时完成");
btnCaptcha.setBackgroundColor(ContextCompat.getColor(MainActivity.this,
android.R.color.holo_blue_light));
btnCaptcha.setTextColor(ContextCompat.getColor(MainActivity.this,
android.R.color.white));
btnCaptcha.setTextSize(18);
btnCaptcha.setText("重新发送");
btnCaptcha.setClickable(true);
}
}