what the function does is deviding the numertor with the denomirator and updates the app’s text view accordingly after every second, the problem is that it doesn’t update the screen its just simply shows the original number of the numerator that is 60.
what do I change in order to make this work?
fun division() {
val numerator = 60
var denominator = 4
repeat(4) {
Thread.sleep(1_000)
findViewById<TextView>(R.id.division_textview).setText("${numerator / denominator}")
denominator--
}
}
3
Answers
Because you are setting (basically overwritting) the text everytime it loops through, you will only see the value of the last increment which would be 60/1 and that’s why you are only seeing 60 value. Try like this:
setText()
was overwriting the text with the new one butappend()
is gonna keep the previous text.This is that dang Codelab again isn’t it? I knew it looked familiar… I already answered a similar question here – but basically, when you run
division
on the main thread (which you must be since you’re messing with UI components), you’re freezing the app because you’re blocking the thread withThread.sleep
The display can’t actually update until your code has finished running, i.e. after you exit the
division
function, because it’s all running on the same thread, and the display update pass comes later. So this is what’s actually happening:60 / 4
– it won’t actually redraw until later, after your code has finished, so there’s no visual change60 / 3
– again you won’t see anything happen yet, but now it’s going to show60 / 3
instead of60 / 4
, because you just updated the state of thatTextView
The last text you set is the result of
60 / 1
, and then your code finishes, so the system can finally get around to updating the display. So the first thing you see after the app stops freezing is60
– it’s not just the numerator, it’s the last calculation from your loop.If you want something to update while the app is running, there are lots of solutions like coroutines,
CountdownTimer
s,post
ing runnables that execute at a specific time, etc. The answer I linked shows how to create a separate thread to run basically the same code on, so you can block it as much as you like without affecting the running of the app. The one thing you don’t do is block the main thread like that Codelab example does. It’s a bad CodelabYou can use
delay
and then call from a coroutine:Then from your Activity/Fragment: