Android开发:完美实现倒计时功能

发布时间:2023-05-14

一、实现原理

倒计时功能的实现原理很简单,就是通过Handler不断地向主线程发送Message,用Message中的arg1来存放倒计时的时间,通过TextView显示出来。当倒计时结束时,停止向主线程发送Message。

二、实现步骤

1、首先在布局文件中添加一个TextView来显示倒计时的时间:

<TextView
    android:id="@+id/tv_countdown"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textSize="20sp"
    android:textColor="@android:color/black" />

2、在Activity中获取TextView的实例,并使用Handler实现倒计时:

public class MainActivity extends AppCompatActivity {
    private TextView mCountdownView;
    private static final int MSG_UPDATE_COUNTDOWN = 1;
    private static final int COUNTDOWN_TIME = 60; // 倒计时60秒
    private int mCountdown = COUNTDOWN_TIME; // 用于记录倒计时的剩余时间
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case MSG_UPDATE_COUNTDOWN:
                    mCountdownView.setText(msg.arg1 + "秒");
                    if (msg.arg1 == 0) {
                        stopCountdown();
                    }
                    break;
            }
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mCountdownView = findViewById(R.id.tv_countdown);
        startCountdown();
    }
    // 开始倒计时
    private void startCountdown() {
        mCountdown = COUNTDOWN_TIME;
        mHandler.post(mCountdownRunnable);
    }
    // 停止倒计时
    private void stopCountdown() {
        mHandler.removeCallbacksAndMessages(null);
    }
    private Runnable mCountdownRunnable = new Runnable() {
        @Override
        public void run() {
            mCountdown--;
            Message msg = mHandler.obtainMessage(MSG_UPDATE_COUNTDOWN);
            msg.arg1 = mCountdown;
            mHandler.sendMessage(msg);
            if (mCountdown > 0) {
                mHandler.postDelayed(this, 1000); // 每隔1秒向主线程发送一次Message
            }
        }
    };
}

三、实现效果

启动应用后,TextView会显示60秒,然后每秒钟减少1秒,直到倒计时结束:

60秒
59秒
58秒
57秒
56秒
……
2秒
1秒
0秒

完整代码如下:

<?xml version="1.0" encoding="utf-8"?>
<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"
    android:gravity="center_horizontal"
    tools:context=".MainActivity">
    <TextView
        android:id="@+id/tv_countdown"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="20sp"
        android:textColor="@android:color/black" />
</LinearLayout>
public class MainActivity extends AppCompatActivity {
    private TextView mCountdownView;
    private static final int MSG_UPDATE_COUNTDOWN = 1;
    private static final int COUNTDOWN_TIME = 60; // 倒计时60秒
    private int mCountdown = COUNTDOWN_TIME; // 用于记录倒计时的剩余时间
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case MSG_UPDATE_COUNTDOWN:
                    mCountdownView.setText(msg.arg1 + "秒");
                    if (msg.arg1 == 0) {
                        stopCountdown();
                    }
                    break;
            }
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mCountdownView = findViewById(R.id.tv_countdown);
        startCountdown();
    }
    // 开始倒计时
    private void startCountdown() {
        mCountdown = COUNTDOWN_TIME;
        mHandler.post(mCountdownRunnable);
    }
    // 停止倒计时
    private void stopCountdown() {
        mHandler.removeCallbacksAndMessages(null);
    }
    private Runnable mCountdownRunnable = new Runnable() {
        @Override
        public void run() {
            mCountdown--;
            Message msg = mHandler.obtainMessage(MSG_UPDATE_COUNTDOWN);
            msg.arg1 = mCountdown;
            mHandler.sendMessage(msg);
            if (mCountdown > 0) {
                mHandler.postDelayed(this, 1000); // 每隔1秒向主线程发送一次Message
            }
        }
    };
}