我正在 Kotlin 中為 Android 制作一個學校專案,這是一個呼吸練習應用程式。我想遍歷一個二維陣列,其中包含某個練習中的步驟和每個步驟的持續時間,并為每個步驟設定一個進度條影片,影片長度為當前步長(以秒為單位)。
二維陣列的示例:
[
["inhale", "10"],
["exhale", "10"],
["inhale", "5"],
["hold", "10"],
["exhale", "5"],
etc..
]
我嘗試了以下 Kotlin 代碼:
var currentExerciseType: String = ""
var currentExerciseDuration: Long = 0
var i = 0
while (i < exerciseList.size) {
motivation_text.append(exerciseList[i][0] " \n")
currentExerciseType = exerciseList[i][0]
currentExerciseDuration = exerciseList[i][1].toLong() * 1000
exercise_type.text = currentExerciseType
val animation = ObjectAnimator.ofInt(progressBar, "progress", 0, 100)
animation.duration = currentExerciseDuration
animation.interpolator = DecelerateInterpolator()
animation.start()
animation.doOnEnd {
i
}
}
這會導致運行此功能時螢屏變黑。我也嘗試使用 for 回圈遍歷陣列,但它似乎并沒有等待每個影片完成,而是在第一個影片仍在運行時在螢屏上顯示最后一步。
知道如何解決這個問題嗎?提前致謝。
uj5u.com熱心網友回復:
您可以使用遞回函式,使用您的代碼 while 將繼續回圈,因為您不等待影片結束。嘗試類似:
private fun animate(i : Int){
//do your things
animation.doOnEnd {
if(i < exerciseList.size)
animate(i 1)
}
.
.
.
//where you need to start the animation
animate(0)
}
uj5u.com熱心網友回復:
您的代碼不起作用的原因是影片是異步運行的。一旦你呼叫start(),影片就會排隊開始,但你當前的 while 回圈代碼會立即繼續。在當前代碼完全完成之前,您在回圈中創建的影片不會啟動,因此將釋放主執行緒以啟動這些影片。代碼直到影片完成后的doOnEnd某個時間才會運行,因此i 永遠不會被呼叫,并且您的 while 回圈將永遠運行而不會釋放主執行緒,因此您的許多重復影片中的任何一個甚至都可以啟動。
因此,要在 while 回圈中設定影片,您需要給每個影片一個延遲,該延遲是所有先前影片持續時間的總和。但要做到這一點并不是很簡單。
一個更簡單的設定方法是創建一個影片串列,然后使用 AnimatorSet 順序播放它們。像這樣的東西(我沒有測驗過。):
val animations = exerciseList.map { exercise ->
val exerciseType: String = exercise[0]
ObjectAnimator.ofInt(progressBar, "progress", 0, 100).apply {
duration = exercise[1].toLong() * 1000
doOnStart {
motivation_text.append(exerciseType " \n")
exercise_type.text = exerciseType
}
}
}
AnimatorSet().run {
playSequentially(animations)
start()
}
如果您不熟悉該map函式,它會通過在 lambda 中運行代碼并回傳值來從源陣列或可迭代物件中創建一個新串列。所以在這種情況下,它會創建一個 ObjectAnimators 串列,對應于原始串列中的每個專案。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/443736.html
下一篇:Kotlin-向空陣列添加值
