Android CountDownTimer 按顺序调用。等待一个完成并开始另一个

问题描述 投票:0回答:1

我正在尝试使用 Java 在我的 Android 应用程序中创建一系列 CountDownTimers,其中每个计时器仅在前一个计时器完成后才启动。该序列需要重复一定数量的轮次,并有一些变化(例如跳过最后一轮的休息时间)。这是我想要的顺序:

  1. 启动 3 秒倒计时器。等待完成
  2. 之后,启动主计时器。等待完成
  3. 然后,启动休息定时器。
  4. 重复该序列指定的轮数。

即使尝试使用 while 循环,我也无法确保每个计时器按顺序运行。关于如何处理这个问题有什么建议吗?这就是我到目前为止所拥有的(尝试使用 While 循环):

package com.example.empty_tv_test;
import android.os.Bundle;
import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import android.os.CountDownTimer;
import android.widget.TextView;
import java.text.DecimalFormat;
import java.text.NumberFormat;

public class MainActivity extends AppCompatActivity {


    private TextView textView;
    private Boolean isThreeSecondsCountDownOver = true;
    private Boolean isTimerRunning = true;
    private Boolean isMainCounterOver = false;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EdgeToEdge.enable(this);
        setContentView(R.layout.activity_main);
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
            Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
            return insets;
        });

        // Initialize the TextView
        textView = findViewById(R.id.textViewTimer);

        // Start CDT 1
        //Start the CountDown
        //Avoiding infite runs
        boolean didThreeSecondsRun = false;
        boolean didMainTimerRun = false;
        boolean didRestTimerRun = false;
        while (isTimerRunning) {
            //Run for as many rounds as necessary /
            //TO-DO Wrap this with FOR loops for Rounds
            //First Check: Is 3 Seconds Countdown?
            if (isThreeSecondsCountDownOver && !didThreeSecondsRun){
                StartCountDownTimer(2000, 1);
                //Turn 3 SEC off
                didThreeSecondsRun = true;
            }
            if (!isThreeSecondsCountDownOver && !didMainTimerRun){
                //3 Seconds Coundown is over, start main counter
                StartCountDownTimer(7000, 2);
                didMainTimerRun = true;
                isTimerRunning = false;
            }
            if(isMainCounterOver && !didRestTimerRun){
                //Finally the Rest Round is Fired
                StartCountDownTimer(8000, 3);
                didThreeSecondsRun = true;
                isTimerRunning = false;
            }
        }


    }//END of onCreate

//TimerType: 1. 3 SEC, 2. Main, 3. Rest
    public void StartCountDownTimer(int time, int whichTimerType){
        new CountDownTimer(time, 1000) {
            @Override
            public void onTick(long millisUntilFinished) {
                // Used for formatting digits to be in 2 digits only
                NumberFormat f = new DecimalFormat("00");
                long hour = (millisUntilFinished / 3600000) % 24;
                long min = (millisUntilFinished / 60000) % 60;
                long sec = (millisUntilFinished / 1000) % 60;
                textView.setText(f.format(hour) + ":" + f.format(min) + ":" + f.format(sec));
            }
            @Override
            public void onFinish() {
                // When the task is over it will print 00:00:00
                textView.setText("ZZZZZZZ");
                if (whichTimerType == 1){
                    isThreeSecondsCountDownOver = false;
                }
                if (whichTimerType == 2){
                    isMainCounterOver = true;
                }
                if (whichTimerType == 3){
                    isMainCounterOver = false;
                }

            }
        }.start();
    }
}

java android multithreading android-studio mobile
1个回答
0
投票

我无法完全理解你的问题,所以我认为你正在尝试在当前计时器 onFinsh 之后执行一些操作,并将一些计时器组合到一个组中,然后你可以决定该组运行多少轮。

我在下面写了一个递归版本:

int red, green, blue;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    button = findViewById(R.id.button2);
    textView = findViewById(R.id.textView);
    root = findViewById(R.id.root);
    button.setOnClickListener(v->{
            startCountDownTimer(2000, 1, 2);
        });
    red = getColor(R.color.red);
    green = getColor(R.color.green);
    blue = getColor(R.color.blue);
}

public void startCountDownTimer(int time, int timerType, int rounds){
    if (rounds == 0) return;
    new CountDownTimer(time, 1000) {
        @Override
        public void onTick(long millisUntilFinished) {
            // Used for formatting digits to be in 2 digits only
            NumberFormat f = new DecimalFormat("00");
            long hour = (millisUntilFinished / 3600000) % 24;
            long min = (millisUntilFinished / 60000) % 60;
            long sec = (millisUntilFinished / 1000) % 60;
            textView.setText(f.format(hour) + ":" + f.format(min) + ":" + f.format(sec));
        }
        @Override
        public void onFinish() {
            int restRounds = rounds;
            if (timerType == 1){
                root.setBackgroundColor(red);
                startCountDownTimer(2000, 2, restRounds);
            }
            if (timerType == 2){
                startCountDownTimer(3000, 3, restRounds);
                root.setBackgroundColor(blue);
            }
            if (timerType == 3){
                restRounds -= 1;
                startCountDownTimer(1000, 1, restRounds);
                root.setBackgroundColor(green);
            }

        }
    }.start();
}

我让rootView在onFinish时改变背景。

© www.soinside.com 2019 - 2024. All rights reserved.