倒计时定时器如何实现onfinish方法

4
我有一个倒计时器,我想在完成方法或某种代码上实现,以便当计时器停止时,文本视图更改为时间到 并启动另一种方法(在活动中)。 为了澄清,计时器给定一个起始数字,按格式从中倒数到零xx:xx

计时器的类:

public class countdown_timer {
private  long pls;
private long millisInFuture;
private long countDownInterval;
private boolean status;
public countdown_timer(long pMillisInFuture, long pCountDownInterval) {
    this.millisInFuture = pMillisInFuture;
    this.countDownInterval = pCountDownInterval;
    this.pls = pMillisInFuture;

    status = false;
    Initialize();
}

public void Stop() {
    status = false;
}
public  void Reset() {
    millisInFuture = pls;
}

public long getCurrentTime() {
    return millisInFuture;
}

public void Start() {
    status = true;
}
public void Initialize()
{
    final Handler handler = new Handler();
    Log.v("status", "starting");
    final Runnable counter = new Runnable(){

        public void run(){
            long sec = millisInFuture/1000;
            if(status) {
                if(millisInFuture <= 0) {
                    Log.v("status", "done");
                } else {
                    Log.v("status", Long.toString(sec) + " seconds remain");
                    millisInFuture -= countDownInterval;
                    handler.postDelayed(this, countDownInterval);
                }
            } else {
                Log.v("status", Long.toString(sec) + " seconds remain and timer has stopped!");
                handler.postDelayed(this, countDownInterval);
            }
        }
    };

    handler.postDelayed(counter, countDownInterval);
}

计时器使用的活动:
 @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_card_game_2);
    //...find views
    mycounterup = new countdown_timer(startcard, 1000);
    mycounterdown = new countdown_timer(startcard, 1000);
    RefreshTimer();
    mycounterdown.Start();

  public void RefreshTimer()
{
    final Handler handler = new Handler();
    final Runnable counter = new Runnable(){

        public void run(){
            int minutes_up_start = (int) (mycounterup.getCurrentTime() / 1000) / 60;
            int seconds_up_start = (int) (mycounterup.getCurrentTime() / 1000) % 60;
            String time_2_up_start_formatted = String.format(Locale.getDefault(), "%02d:%02d", minutes_up_start, seconds_up_start);
            card_2_up.setText(time_2_up_start_formatted);

            int minutes_down_start = (int) (mycounterdown.getCurrentTime() / 1000) / 60;
            int seconds_down_start = (int) (mycounterdown.getCurrentTime() / 1000) % 60;
            String card_2_down_start_formatted = String.format(Locale.getDefault(), "%02d:%02d", minutes_down_start, seconds_down_start);
            card_2_down.setText(card_2_down_start_formatted);
            handler.postDelayed(this, 100);
        }
    };

    handler.postDelayed(counter, 100);
}

你可以尝试在你的计时器类中扩展 CountDownTimer - Cagri Yalcin
@Cagri Yalcin,您能告诉我如何做吗? - user9478448
为什么不使用内置的CountDownTimer类? - godot
@godot 你是什么意思? - user9478448
@manos 请检查我的答案。希望能有所帮助。 - Cagri Yalcin
2个回答

4

您可以使用倒计时器

new CountDownTimer(endsIn * 1000, 1000) { 
public void onTick(long millisUntilFinished) { 
           timerTextView.setText(String.valueOf(millisUntilFinished/1000);
 } 
public void onFinish() {
} 
}.start();

OR:

扩展 CountDownTimer 类:

public class countdown_timer extends CountDownTimer {
    TextView textView;
    @Override
    public void onTick(long millisInFuture) {
        long sec = millisInFuture/1000;
            if(millisInFuture <= 0) {
                Log.v("status", "done");

        } else {
            Log.v("status", Long.toString(sec) + " seconds remain and timer has stopped!");
        }
    }

    @Override
    public void onFinish() {
        if(textView != null){
            // change text in your textview
        }
    }



    public countdown_timer(long pMillisInFuture, long pCountDownInterval) {
        super(pMillisInFuture, pCountDownInterval);

    }
    public countdown_timer(TextView textView, long pMillisInFuture, long pCountDownInterval) {
        super(pMillisInFuture, pCountDownInterval);
        this.textView = textView;




    }






}

这里有两个构造函数,其中一个与您的示例中相同,而另一个可以传递 TextView 对象,并在 onFinish() 方法中使用它。

更新2:

这是在 Activity 中的 CountDownTimer

public class MainActivity extends AppCompatActivity {

    TextView textView;
    CountDownTimer mycounterdown;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        long startcard = 10000;
        textView = (TextView) findViewById(R.id.test);

        mycounterdown = new CountDownTimer(startcard, 1000) {
            @Override
            public void onTick(long mycounterup) {
                int minutes_up_start = (int) (mycounterup / 1000) / 60;
                int seconds_up_start = (int) (mycounterup / 1000) % 60;
                String time_2_up_start_formatted = String.format(Locale.getDefault(), "%02d:%02d", minutes_up_start, seconds_up_start);
                textView.setText(time_2_up_start_formatted);
            }

            @Override
            public void onFinish() {
                // call here other methods from activity

                testMethod();
            }
        };
        mycounterdown.start();

    }
    public void testMethod(){
        Toast.makeText(MainActivity.this, "Test Method called", Toast.LENGTH_SHORT).show();
    }

}

更新 3:如果最后一个刻度是1而不是0,则将倒计时间隔更改为500而不是1000:

public class MainActivity extends AppCompatActivity {

    TextView textView;
    CountDownTimer mycounterdown;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        long startcard = 10000;
        textView = (TextView) findViewById(R.id.test);

        mycounterdown = new CountDownTimer(startcard, 500) {
            @Override
            public void onTick(long mycounterup) {
                int minutes_up_start = (int) (mycounterup / 1000) / 60;
                int seconds_up_start = (int) (mycounterup / 1000) % 60;
                String time_2_up_start_formatted = String.format(Locale.getDefault(), "%02d:%02d", minutes_up_start, seconds_up_start);
                textView.setText(time_2_up_start_formatted);
            }

            @Override
            public void onFinish() {
                // call here other methods from activity

                testMethod();
            }
        };
        mycounterdown.start();

    }
    public void testMethod(){
        Toast.makeText(MainActivity.this, "Test Method called", Toast.LENGTH_SHORT).show();
    }

}

注意:请参考此答案


问题在于传统的倒计时器存在许多错误,比如跳过最后一次滴答声,这就是为什么我创建了一个类来解决这个问题。 - user9478448
谢谢您的帮助,但我不想添加一个新的CountDownTimer,我想使用计时器类中已有的CountDownTimer,并加上一个on finish方法。 - user9478448
因为自定义的更准确。 - user9478448
你遇到了什么样的不准确性问题? - godot
请再次查看,我更新了我的答案。我尝试重写您的逻辑,而不使用自定义倒计时器。 - godot
显示剩余8条评论

1
首先,在你的计时器类中扩展CountDownTimer
public class countdown_timer extends CountDownTimer {

}

这允许您实现一些方法。
@Override
public void onTick(long l) {

}

@Override
public void onFinish() {

}

此外,您必须实现与超类匹配的构造函数。您还可以添加一些额外的参数。例如TextView

TextView textView;
public countdown_timer(long millisInFuture, long countDownInterval, TextView txt) {
    super(millisInFuture, countDownInterval);
    textView = txt;
}

onFinish()是你想要的。同时确保你将这个类用作CountDownTimer。然后你就能启动计时器了。 希望对你有所帮助。


当我将类扩展到CountDownTimer时,它在以下代码中显示错误: public countdown_timer(long pMillisInFuture, long pCountDownInterval) "没有默认构造函数可用"。 - user9478448
你必须实现与你的父类匹配的构造函数。编辑我的答案。 - Cagri Yalcin
到目前为止还不错,但是on finish方法在计时器类中而不是我的活动中,所以我无法使用它来更改文本。 - user9478448
当计时器停止时,我如何启动另一个方法? - user9478448
哪个方法? - Cagri Yalcin
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接