在XML中我有两个EditText。在一个EditText中,用户可以输入分钟数,在另一个EditText中,可以输入秒数。在点击完成按钮后,秒EditText应开始倒计时并每秒更新其文本。
此外,如何使其保持更新直到达到零分钟和零秒?
界面化的方式。
import android.os.CountDownTimer;
/**
* Created by saikiran on 07-03-2016.
*/
public class CountDownTimerCustom extends CountDownTimer {
private TimeTickListener mTickListener;
private TimeFinishListener mFinishListener;
private long millisUntilFinished;
public CountDownTimerCustom(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
public void updateTickAndFinishListener(TimeTickListener tickListener) {
mTickListener = tickListener;
}
public void updateFinishListner(TimeFinishListener listener) {
mFinishListener = listener;
}
public long getCurrentMs() {
return millisUntilFinished;
}
public int getCurrentSec() {
return (int) millisUntilFinished / 1000;
}
@Override
public void onTick(long millisUntilFinished) {
this.millisUntilFinished = millisUntilFinished;
if (mTickListener != null)
mTickListener.onTick(millisUntilFinished);
}
@Override
public void onFinish() {
if (mTickListener != null)
mTickListener.onFinished();
mFinishListener.onFinished();
}
public interface TimeTickListener {
void onTick(long mMillisUntilFinished);
void onFinished();
}
public interface TimeFinishListener {
void onFinished();
}
}
这是我在Kotlin中使用的解决方案:
最初的回答
private fun startTimer()
{
Log.d(TAG, ":startTimer: timeString = '$timeString'")
object : CountDownTimer(TASK_SWITCH_TIMER, 250)
{
override fun onTick(millisUntilFinished: Long)
{
val secondsUntilFinished : Long =
Math.ceil(millisUntilFinished.toDouble()/1000).toLong()
val timeString = "${TimeUnit.SECONDS.toMinutes(secondsUntilFinished)}:" +
"%02d".format(TimeUnit.SECONDS.toSeconds(secondsUntilFinished))
Log.d(TAG, ":startTimer::CountDownTimer:millisUntilFinished = $ttlseconds")
Log.d(TAG, ":startTimer::CountDownTimer:millisUntilFinished = $millisUntilFinished")
}
@SuppressLint("SetTextI18n")
override fun onFinish()
{
timerTxtVw.text = "0:00"
gameStartEndVisibility(true)
}
}.start()
}
private void startTimer() {
startTimer = new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
long sec = (TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished)));
Log.e(TAG, "onTick: "+sec );
tv_timer.setText(String.format("( %02d SEC )", sec));
if(sec == 1)
{
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
tv_timer.setText("( 00 SEC )");
}
}, 1000);
}
}
public void onFinish() {
tv_timer.setText("Timer finish");
}
}.start();
}
使用 Rx 的简洁解决方案,可能会有人感兴趣
数字的扩展(Double、Float、Long 等):
fun Number.countDownTimer(tick: Long = 1, timeUnit: TimeUnit = TimeUnit.SECONDS): Observable<Long> {
val count = this.toLong()
return Observable.interval(tick, timeUnit)
.take(count)
.map { count - it - 1 }
}
用法
60.countDownTimer().subscribe { textView.text = it }
// the count down timer
new CountDownTimer(30000, 1000)
{
@Override
public void onTick(long l) {
}
@Override
public void onFinish() {
//on finish the count down timer finsih
}
}
}
}.start();
我使用Kotlin Flows实现了一个很酷的定时器方法,因此您可以在ViewModel中实现它。
var countDownInit = 30
fun countDownTimer() = flow<Int> {
var time = countDownInit
emit(time)
while (true){
time--
delay(1000L)
countDownInit = time
emit(time)
}
}
然后在您的活动或片段中,只需像这样调用此函数
lifecycleScope.launch {
lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED){
viewModel.countDownTimer().collect{time->
//and update UI
//and for the finish section you can just use this
this.cancel()
}
}
}
现在应用程序生命周期的暂停中没有崩溃或其他问题,而且你总是拥有最新的秒数。