我在 XML 中有两个 EditText。在一个 EditText 中,用户可以输入一个数字为分钟,而在另一个 EditText 中,一个数字为秒。单击完成按钮后,EditText 的秒数应该开始倒计时并每秒更新其文本。
此外,我怎样才能让它保持更新,直到它达到零分钟和零秒?
new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
//here you can have your logic to set text to edittext
}
public void onFinish() {
mTextField.setText("done!");
}
}.start();
请参阅此链接。
如果您使用以下代码(如接受的答案中所述),
new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
//here you can have your logic to set text to edittext
}
public void onFinish() {
mTextField.setText("done!");
}
}.start();
如果您不仔细清理引用,它将导致您使用此代码的活动实例的内存泄漏。
使用以下代码
//Declare timer
CountDownTimer cTimer = null;
//start timer function
void startTimer() {
cTimer = new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
}
};
cTimer.start();
}
//cancel timer
void cancelTimer() {
if(cTimer!=null)
cTimer.cancel();
}
每当调用拥有的 Activity/Fragment 中的onDestroy()/onDestroyView( ) 时,您都需要调用cTtimer.cancel() 。
MainActivity.java
package com.zeustechnocrats.countdown;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
import java.text.SimpleDateFormat;
import java.util.Date;
public class MainActivity extends AppCompatActivity {
private String EVENT_DATE_TIME = "2021-12-31 10:30:00";
private String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
private LinearLayout linear_layout_1, linear_layout_2;
private TextView tv_days, tv_hour, tv_minute, tv_second;
private Handler handler = new Handler();
private Runnable runnable;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.count_down);
initUI();
countDownStart();
}
private void initUI() {
linear_layout_1 = findViewById(R.id.linear_layout_1);
linear_layout_2 = findViewById(R.id.linear_layout_2);
tv_days = findViewById(R.id.tv_days);
tv_hour = findViewById(R.id.tv_hour);
tv_minute = findViewById(R.id.tv_minute);
tv_second = findViewById(R.id.tv_second);
}
private void countDownStart() {
runnable = new Runnable() {
@Override
public void run() {
try {
handler.postDelayed(this, 1000);
SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);
Date event_date = dateFormat.parse(EVENT_DATE_TIME);
Date current_date = new Date();
if (!current_date.after(event_date)) {
long diff = event_date.getTime() - current_date.getTime();
long Days = diff / (24 * 60 * 60 * 1000);
long Hours = diff / (60 * 60 * 1000) % 24;
long Minutes = diff / (60 * 1000) % 60;
long Seconds = diff / 1000 % 60;
//
tv_days.setText(String.format("%02d", Days));
tv_hour.setText(String.format("%02d", Hours));
tv_minute.setText(String.format("%02d", Minutes));
tv_second.setText(String.format("%02d", Seconds));
} else {
linear_layout_1.setVisibility(View.VISIBLE);
linear_layout_2.setVisibility(View.GONE);
handler.removeCallbacks(runnable);
}
} catch (Exception e) {
e.printStackTrace();
}
}
};
handler.postDelayed(runnable, 0);
}
protected void onStop() {
super.onStop();
handler.removeCallbacks(runnable);
}
}
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white"
android:orientation="horizontal">
<LinearLayout
android:id="@+id/linear_layout_1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/black"
android:gravity="center_horizontal"
android:visibility="gone">
<TextView
android:id="@+id/tv_event"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:text="Android Event Start"
android:textColor="@android:color/white"
android:textSize="20dp"
android:textStyle="normal" />
</LinearLayout>
<LinearLayout
android:id="@+id/linear_layout_2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/black"
android:visibility="visible">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="@+id/tv_days"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="00"
android:textColor="@android:color/white"
android:textSize="20dp"
android:textStyle="bold" />
<TextView
android:id="@+id/tv_days_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Days"
android:textColor="@android:color/white"
android:textSize="20dp"
android:textStyle="normal" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="@+id/tv_hour"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="00"
android:textColor="@android:color/white"
android:textSize="20dp"
android:textStyle="bold" />
<TextView
android:id="@+id/tv_hour_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Hour"
android:textColor="@android:color/white"
android:textSize="20dp"
android:textStyle="normal" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="@+id/tv_minute"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="00"
android:textColor="@android:color/white"
android:textSize="20dp"
android:textStyle="bold" />
<TextView
android:id="@+id/tv_minute_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Minute"
android:textColor="@android:color/white"
android:textSize="20dp"
android:textStyle="normal" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="@+id/tv_second"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="00"
android:textColor="@android:color/white"
android:textSize="20dp"
android:textStyle="bold" />
<TextView
android:id="@+id/tv_second_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Second"
android:textColor="@android:color/white"
android:textSize="20dp"
android:textStyle="normal" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
只需复制粘贴以下代码......
主要活动
包 com.example.countdowntimer;
import java.util.concurrent.TimeUnit;
import android.app.Activity;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.widget.TextView;
public class MainActivity extends Activity {
TextView text1;
private static final String FORMAT = "%02d:%02d:%02d";
int seconds , minutes;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text1=(TextView)findViewById(R.id.textView1);
new CountDownTimer(16069000, 1000) { // adjust the milli seconds here
public void onTick(long millisUntilFinished) {
text1.setText(""+String.format(FORMAT,
TimeUnit.MILLISECONDS.toHours(millisUntilFinished),
TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished) - TimeUnit.HOURS.toMinutes(
TimeUnit.MILLISECONDS.toHours(millisUntilFinished)),
TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) - TimeUnit.MINUTES.toSeconds(
TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished))));
}
public void onFinish() {
text1.setText("done!");
}
}.start();
}
}
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="34dp"
android:layout_marginTop="58dp"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceMedium" />
</RelativeLayout>
只需通过传递秒数和 textview 对象来调用下面的函数
public void reverseTimer(int Seconds,final TextView tv){
new CountDownTimer(Seconds* 1000+1000, 1000) {
public void onTick(long millisUntilFinished) {
int seconds = (int) (millisUntilFinished / 1000);
int minutes = seconds / 60;
seconds = seconds % 60;
tv.setText("TIME : " + String.format("%02d", minutes)
+ ":" + String.format("%02d", seconds));
}
public void onFinish() {
tv.setText("Completed");
}
}.start();
}
倒计时计时器与小时分钟和秒
public void reverseTimer(int Seconds, final TextView tv) {
new CountDownTimer(Seconds * 1000 + 1000, 1000) {
public void onTick(long millisUntilFinished) {
int seconds = (int) (millisUntilFinished / 1000);
int hours = seconds / (60 * 60);
int tempMint = (seconds - (hours * 60 * 60));
int minutes = tempMint / 60;
seconds = tempMint - (minutes * 60);
tv.setText("TIME : " + String.format("%02d", hours)
+ ":" + String.format("%02d", minutes)
+ ":" + String.format("%02d", seconds));
}
public void onFinish() {
tv.setText("Completed");
}
}.start();
}
使用 Kotlin:
var timer = object: CountDownTimer(30000, 1000) {
override fun onTick(millisUntilFinished: Long) {
tvTimer.setText("seconds remaining: " + millisUntilFinished / 1000)
}
override fun onFinish() {
tvTimer.setText("done!")
}
}
timer.start()
输出:01:30
new CountDownTimer(90000, 1000) {
public void onTick(long duration) {
//tTimer.setText("seconds remaining: " + millisUntilFinished / 1000);
//here you can have your logic to set text to edittext resource id
// Duration
long Mmin = (duration / 1000) / 60;
long Ssec = (duration / 1000) % 60;
if (Ssec < 10) {
tTimer.setText("" + Mmin + ":0" + Ssec);
} else tTimer.setText("" + Mmin + ":" + Ssec);
}
public void onFinish() {
tTimer.setText("00:00");
}
}.start();
接口方式。
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()
}
public class Scan extends AppCompatActivity {
int minute;
long min;
TextView tv_timer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scan2);
tv_timer=findViewById(R.id.tv_timer);
minute=Integer.parseInt("Your time in string form like 10");
min= minute*60*1000;
counter(min);
}
private void counter(long min) {
CountDownTimer timer = new CountDownTimer(min, 1000) {
public void onTick(long millisUntilFinished) {
int seconds = (int) (millisUntilFinished / 1000) % 60;
int minutes = (int) ((millisUntilFinished / (1000 * 60)) % 60);
int hours = (int) ((millisUntilFinished / (1000 * 60 * 60)) % 24);
tv_timer.setText(String.format("%d:%d:%d", hours, minutes, seconds));
}
public void onFinish() {
Toast.makeText(getApplicationContext(), "Your time has been completed",
Toast.LENGTH_LONG).show();
}
};
timer.start();
}
}
var futureMinDate = Date()
val sdf = SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH)
try {
futureMinDate = sdf.parse("2019-08-22")
} catch (e: ParseException) {
e.printStackTrace()
}
// Here futureMinDate.time Returns the number of milliseconds since January 1, 1970, 00:00:00 GM
// So we need to subtract the millis from current millis to get actual millis
object : CountDownTimer(futureMinDate.time - System.currentTimeMillis(), 1000) {
override fun onTick(millisUntilFinished: Long) {
val sec = (millisUntilFinished / 1000) % 60
val min = (millisUntilFinished / (1000 * 60)) % 60
val hr = (millisUntilFinished / (1000 * 60 * 60)) % 24
val day = ((millisUntilFinished / (1000 * 60 * 60)) / 24).toInt()
val formattedTimeStr = if (day > 1) "$day days $hr : $min : $sec"
else "$day day $hr : $min : $sec"
tvFlashDealCountDownTime.text = formattedTimeStr
}
override fun onFinish() {
tvFlashDealCountDownTime.text = "Done!"
}
}.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();
}
// 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 流实现了一种很酷的计时器方法,因此您可以在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()
}
}
}
现在在应用程序生命周期暂停时出现崩溃或某事,并且您始终拥有最新的秒数