实现覆盖 activity 的倒数计时器

Implementing a countdown timer overlaying the activity

我有一个 activity 正在根据参考曲目实时评估演唱者。我想要的是,当此人单击练习按钮时,屏幕上会出现 5 秒的倒计时,屏幕上的所有组件都已停用。我还想在屏幕上显示倒计时。我的想法是在我的 Activity 视图之上有一个透明的灰色覆盖层,并在其上显示倒计时。 我正在考虑在 Android-SDK 中使用 AsyncTaskCountDownTimer 实现逻辑。实现可视化的最佳方法是什么?

选择 CountDownTimer,因为它提供开箱即用的滴答功能:

new CountDownTimer ( 5000, 1000 ) {
  @Override 
  public void onTick( long millisUntilFinished ) {
    countDownView.setText( (int)( millisUntilFinished / 1000 ) + "sec left" );
  }

  @Override 
  public void onFinish() {
    overlay.setVisibility( GONE );
  }
}.start()

我终于能够在不使用 CountDownTimer 的情况下实现这一目标。为此,我创建了一个 class 扩展 AsyncTask 如下:

    public class CountdownTask extends AsyncTask<Integer, Integer, Integer> {

    private ICountdownView mCountdownView;

    private static final String TAG = "CountdownTask";

    public CountdownTask(ICountdownView countdownView) {
        this.mCountdownView = countdownView;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        // Code to set up the timer ...
        mCountdownView.initCountdownView();

    }

    @Override
    protected Integer doInBackground(Integer... params) {
        // setting the default number of steps ..
        int countdownSteps = 5;
        // reading the number of steps if mentioned in the parameters
        if (params.length >= 1 && params[0] != null) {
            countdownSteps = params[0];
        }

        // setting the default step duration in milliseconds ..
        int stepDur = 1000;
        // reading the step duration if mentioned in the parameters
        if (params.length >= 2 && params[1] != null) {
            stepDur = params[1];
        }

        for (int i = 0; i < countdownSteps; i++) {
            publishProgress(countdownSteps - i);
            sleep(stepDur);
        }
        return null;
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);
        mCountdownView.updateCountdownView(values[0]);
    }

    @Override
    protected void onPostExecute(Integer integer) {
        super.onPostExecute(integer);
        mCountdownView.destroyCountDownView();
    }

    private void sleep(int mDelay) {
        try {
            Thread.sleep(mDelay);
        } catch (InterruptedException e) {
            Log.e(TAG, e.toString());
        }
    }
}

为了更新到UI,我创建了一个接口ICountdownView。 activity需要倒计时需要实现这个接口,然后使用new CountdownTask(this)初始化CountdownTask,其中this引用activity[=40] =].界面ICountdownView如下:

    public interface ICountdownView {

    void initCountdownView();

    void updateCountdownView(int timeLeft);

    void destroyCountDownView();
}

在你的 activity 中,你可以通过任何你想要的动画来实现所有这些方法。就我而言,在 initCountdownView() 上,我初始化了一个具有透明背景且没有 header 的对话框。在每个 updateCountdownView(int timeLeft) 上,我都会在对话框中显示剩余时间并为其设置动画。在 destroyCountDownView() 上,我 dismiss() 对话框并继续下一步我需要做的任何事情。希望这对您有所帮助!

PS:您可以启动 CountdownTask,步数和每个步骤的持续时间以毫秒为单位,例如:

mCountdownTask.execute(5, 1000);

上述语句使倒计时分 5 步执行,每步长 1000 毫秒(1 秒)。如果用户不提供任何参数,这也是 CountdownTask 的默认行为。