如何在 Kotlin 中创建一个简单的倒数计时器?
How to create a simple countdown timer in Kotlin?
我知道如何在 Java 中创建一个简单的倒数计时器。但我想在 Kotlin 中创建这个。
package android.os;
new CountDownTimer(20000, 1000) {
public void onTick(long millisUntilFinished) {
mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
}
public void onFinish() {
mTextField.setText("Time's finished!");
}
}.start();
我如何使用 Kotlin 来做到这一点?
尝试像这样使用对象:
var countDownTimer = object : CountDownTimer(2000, 1000) {
// override object functions here, do it quicker by setting cursor on object, then type alt + enter ; implement members
}
试试这个网站:https://try.kotlinlang.org/#/Kotlin%20Koans/Introduction/Java%20to%20Kotlin%20conversion/Task.kt
您的右上角有一个小按钮 "Convert from Java",可能对您有用。
编辑:
不要忘记在需要时启动此对象,方法是在声明末尾添加 .start()
,或在 activity / 片段中的任何位置添加:
countDownTimer.start()
您可以使用 Kotlin 对象:
val timer = object: CountDownTimer(20000, 1000) {
override fun onTick(millisUntilFinished: Long) {...}
override fun onFinish() {...}
}
timer.start()
Chronometer 可以设置为倒计时,在我看来这是最简单的方法。
在布局中添加 Chronometer 视图 xml,示例
<Chronometer
android:id="@+id/view_timer"
tools:targetApi="24"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
然后在您的 activity 或片段中:
view_timer.isCountDown = true
view_timer.base = SystemClock.elapsedRealtime() + 20000
view_timer.start()
我在 Kotlin 中解决了我的计时器问题,如下所示:
class Timer {
private val job = SupervisorJob()
private val scope = CoroutineScope(Dispatchers.Default + job)
private fun startCoroutineTimer(delayMillis: Long = 0, repeatMillis: Long = 0, action: () -> Unit) = scope.launch(Dispatchers.IO) {
delay(delayMillis)
if (repeatMillis > 0) {
while (true) {
action()
delay(repeatMillis)
}
} else {
action()
}
}
private val timer: Job = startCoroutineTimer(delayMillis = 0, repeatMillis = 20000) {
Log.d(TAG, "Background - tick")
doSomethingBackground()
scope.launch(Dispatchers.Main) {
Log.d(TAG, "Main thread - tick")
doSomethingMainThread()
}
}
fun startTimer() {
timer.start()
}
fun cancelTimer() {
timer.cancel()
}
//...
}
我已经将协程用于计时器。
如果你想用天时分秒显示倒计时
private lateinit var countDownTimer:CountDownTimer
.
.
.
fun printDifferenceDateForHours() {
val currentTime = Calendar.getInstance().time
val endDateDay = "03/02/2020 21:00:00"
val format1 = SimpleDateFormat("dd/MM/yyyy hh:mm:ss",Locale.getDefault())
val endDate = format1.parse(endDateDay)
//milliseconds
var different = endDate.time - currentTime.time
countDownTimer = object : CountDownTimer(different, 1000) {
override fun onTick(millisUntilFinished: Long) {
var diff = millisUntilFinished
val secondsInMilli: Long = 1000
val minutesInMilli = secondsInMilli * 60
val hoursInMilli = minutesInMilli * 60
val daysInMilli = hoursInMilli * 24
val elapsedDays = diff / daysInMilli
diff %= daysInMilli
val elapsedHours = diff / hoursInMilli
diff %= hoursInMilli
val elapsedMinutes = diff / minutesInMilli
diff %= minutesInMilli
val elapsedSeconds = diff / secondsInMilli
txt_timeleft.text = "$elapsedDays days $elapsedHours hs $elapsedMinutes min $elapsedSeconds sec"
}
override fun onFinish() {
txt_timeleft.text = "done!"
}
}.start()
}
如果您正在导航到另一个 activity/fragment,请确保取消倒计时
countDownTimer.cancel()
代码输出
51 days 17 hs 56 min 5 sec
class CustomCountDownTimer(var mutableLiveData: MutableLiveData<String>) {
lateinit var timer: CountDownTimer
val zone = ZoneId.systemDefault()
val startDateTime: ZonedDateTime = LocalDateTime.now().atZone(zone)
fun start(endOn: Long) {
if (this::timer.isInitialized) {
return
}
timer = object : CountDownTimer(endOn * 1000, 1000) {
override fun onTick(millisUntilFinished: Long) {
val stringBuilder = StringBuilder()
val endDateTime: ZonedDateTime =
Instant.ofEpochMilli(millisUntilFinished).atZone(ZoneId.systemDefault())
.toLocalDateTime().atZone(zone)
var diff: Duration = Duration.between(startDateTime, endDateTime)
if (diff.isZero() || diff.isNegative) {
stringBuilder.append("Already ended!")
} else {
val days: Long = diff.toDays()
if (days != 0L) {
stringBuilder.append("${days}day : ")
diff = diff.minusDays(days)
}
val hours: Long = diff.toHours()
stringBuilder.append("${hours}hr : ")
diff = diff.minusHours(hours)
val minutes: Long = diff.toMinutes()
stringBuilder.append("${minutes}min : ")
diff = diff.minusMinutes(minutes)
val seconds: Long = diff.getSeconds()
stringBuilder.append("${seconds}sec")
}
mutableLiveData.postValue(stringBuilder.toString())
//Log.d("CustomCountDownTimer", stringBuilder.toString())
}
override fun onFinish() {
}
}
timer.start()
}
fun getTimerState(): LiveData<String> {
return mutableLiveData
}
}
使用方法:
val liveData: MutableLiveData<String> = MutableLiveData()
val customCountDownTimer = CustomCountDownTimer(liveData)
customCountDownTimer.start(1631638786) //Epoch timestamp
customCountDownTimer.mutableLiveData.observe(this, Observer { counterState ->
counterState?.let {
println(counterState)
}
})
输出:
22hr : 42min : 51sec
//当剩余时间不足 4 小时时
1day : 23hr : 52min : 44sec
// 在其他情况下
使用 Chronometer 用于 minapi=24
:
<Chronometer
android:id="@+id/timer_expire_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/spacing_m"
android:countDown="true"
android:textColor="@color/white"
android:textSize="@dimen/text_size_huge"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:targetApi="24" />
在科特林中:
binding.timerExpireTime.apply {
base = SystemClock.elapsedRealtime()
start()
}
对于未来的读者,您可以在 Kotlin
.
中使用 built-in timer
内联函数
示例:
import kotlin.concurrent.timer
....
....
timer(initialDelay = 1000L, period = 1000L ) {
launch {
executeTask()
}
}
CountDownTimer 在 Kotlin 中:
object: CountDownTimer(3000, 1000){
override fun onTick(p0: Long) {}
override fun onFinish() {
//add your code here
}
}.start()
我知道如何在 Java 中创建一个简单的倒数计时器。但我想在 Kotlin 中创建这个。
package android.os;
new CountDownTimer(20000, 1000) {
public void onTick(long millisUntilFinished) {
mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
}
public void onFinish() {
mTextField.setText("Time's finished!");
}
}.start();
我如何使用 Kotlin 来做到这一点?
尝试像这样使用对象:
var countDownTimer = object : CountDownTimer(2000, 1000) {
// override object functions here, do it quicker by setting cursor on object, then type alt + enter ; implement members
}
试试这个网站:https://try.kotlinlang.org/#/Kotlin%20Koans/Introduction/Java%20to%20Kotlin%20conversion/Task.kt
您的右上角有一个小按钮 "Convert from Java",可能对您有用。
编辑:
不要忘记在需要时启动此对象,方法是在声明末尾添加 .start()
,或在 activity / 片段中的任何位置添加:
countDownTimer.start()
您可以使用 Kotlin 对象:
val timer = object: CountDownTimer(20000, 1000) {
override fun onTick(millisUntilFinished: Long) {...}
override fun onFinish() {...}
}
timer.start()
Chronometer 可以设置为倒计时,在我看来这是最简单的方法。
在布局中添加 Chronometer 视图 xml,示例
<Chronometer
android:id="@+id/view_timer"
tools:targetApi="24"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
然后在您的 activity 或片段中:
view_timer.isCountDown = true
view_timer.base = SystemClock.elapsedRealtime() + 20000
view_timer.start()
我在 Kotlin 中解决了我的计时器问题,如下所示:
class Timer {
private val job = SupervisorJob()
private val scope = CoroutineScope(Dispatchers.Default + job)
private fun startCoroutineTimer(delayMillis: Long = 0, repeatMillis: Long = 0, action: () -> Unit) = scope.launch(Dispatchers.IO) {
delay(delayMillis)
if (repeatMillis > 0) {
while (true) {
action()
delay(repeatMillis)
}
} else {
action()
}
}
private val timer: Job = startCoroutineTimer(delayMillis = 0, repeatMillis = 20000) {
Log.d(TAG, "Background - tick")
doSomethingBackground()
scope.launch(Dispatchers.Main) {
Log.d(TAG, "Main thread - tick")
doSomethingMainThread()
}
}
fun startTimer() {
timer.start()
}
fun cancelTimer() {
timer.cancel()
}
//...
}
我已经将协程用于计时器。
如果你想用天时分秒显示倒计时
private lateinit var countDownTimer:CountDownTimer
.
.
.
fun printDifferenceDateForHours() {
val currentTime = Calendar.getInstance().time
val endDateDay = "03/02/2020 21:00:00"
val format1 = SimpleDateFormat("dd/MM/yyyy hh:mm:ss",Locale.getDefault())
val endDate = format1.parse(endDateDay)
//milliseconds
var different = endDate.time - currentTime.time
countDownTimer = object : CountDownTimer(different, 1000) {
override fun onTick(millisUntilFinished: Long) {
var diff = millisUntilFinished
val secondsInMilli: Long = 1000
val minutesInMilli = secondsInMilli * 60
val hoursInMilli = minutesInMilli * 60
val daysInMilli = hoursInMilli * 24
val elapsedDays = diff / daysInMilli
diff %= daysInMilli
val elapsedHours = diff / hoursInMilli
diff %= hoursInMilli
val elapsedMinutes = diff / minutesInMilli
diff %= minutesInMilli
val elapsedSeconds = diff / secondsInMilli
txt_timeleft.text = "$elapsedDays days $elapsedHours hs $elapsedMinutes min $elapsedSeconds sec"
}
override fun onFinish() {
txt_timeleft.text = "done!"
}
}.start()
}
如果您正在导航到另一个 activity/fragment,请确保取消倒计时
countDownTimer.cancel()
代码输出
51 days 17 hs 56 min 5 sec
class CustomCountDownTimer(var mutableLiveData: MutableLiveData<String>) {
lateinit var timer: CountDownTimer
val zone = ZoneId.systemDefault()
val startDateTime: ZonedDateTime = LocalDateTime.now().atZone(zone)
fun start(endOn: Long) {
if (this::timer.isInitialized) {
return
}
timer = object : CountDownTimer(endOn * 1000, 1000) {
override fun onTick(millisUntilFinished: Long) {
val stringBuilder = StringBuilder()
val endDateTime: ZonedDateTime =
Instant.ofEpochMilli(millisUntilFinished).atZone(ZoneId.systemDefault())
.toLocalDateTime().atZone(zone)
var diff: Duration = Duration.between(startDateTime, endDateTime)
if (diff.isZero() || diff.isNegative) {
stringBuilder.append("Already ended!")
} else {
val days: Long = diff.toDays()
if (days != 0L) {
stringBuilder.append("${days}day : ")
diff = diff.minusDays(days)
}
val hours: Long = diff.toHours()
stringBuilder.append("${hours}hr : ")
diff = diff.minusHours(hours)
val minutes: Long = diff.toMinutes()
stringBuilder.append("${minutes}min : ")
diff = diff.minusMinutes(minutes)
val seconds: Long = diff.getSeconds()
stringBuilder.append("${seconds}sec")
}
mutableLiveData.postValue(stringBuilder.toString())
//Log.d("CustomCountDownTimer", stringBuilder.toString())
}
override fun onFinish() {
}
}
timer.start()
}
fun getTimerState(): LiveData<String> {
return mutableLiveData
}
}
使用方法:
val liveData: MutableLiveData<String> = MutableLiveData()
val customCountDownTimer = CustomCountDownTimer(liveData)
customCountDownTimer.start(1631638786) //Epoch timestamp
customCountDownTimer.mutableLiveData.observe(this, Observer { counterState ->
counterState?.let {
println(counterState)
}
})
输出:
22hr : 42min : 51sec
//当剩余时间不足 4 小时时
1day : 23hr : 52min : 44sec
// 在其他情况下
使用 Chronometer 用于 minapi=24
:
<Chronometer
android:id="@+id/timer_expire_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/spacing_m"
android:countDown="true"
android:textColor="@color/white"
android:textSize="@dimen/text_size_huge"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:targetApi="24" />
在科特林中:
binding.timerExpireTime.apply {
base = SystemClock.elapsedRealtime()
start()
}
对于未来的读者,您可以在 Kotlin
.
timer
内联函数
示例:
import kotlin.concurrent.timer
....
....
timer(initialDelay = 1000L, period = 1000L ) {
launch {
executeTask()
}
}
CountDownTimer 在 Kotlin 中:
object: CountDownTimer(3000, 1000){
override fun onTick(p0: Long) {}
override fun onFinish() {
//add your code here
}
}.start()