0

I have a button in my app that calculates something. When the user taps the button, the button should be disabled. When I'm using following example my button is disabled after the loop has finished. I want the button to be disabled before the loop starts. How can I do this with the example below?

fun calc() {
    myButton.isEnabled = false
    for (x in 0 until 1000000000) {
        println(x)
    }
}
Son Truong
  • 13,661
  • 5
  • 32
  • 58
axeldion
  • 99
  • 8
  • 1
    Once you enter the loop, the UI will not update until you finish the loop. I don't know the Kotlin syntax, but you basically need to run this loop on another thread. In Java you could use new Handler().postDelayed(new Runnable(...)) – Dan Baruch Nov 17 '20 at 13:22
  • 1
    @DanBaruch handler will post the runnable back to UI thread, so same problem will occur, instantiate a new Thread instead. In kotlin, just use `activity.lifecycleScope.launch(Dispatchers.Default) { ... }` – Animesh Sahu Nov 17 '20 at 13:26
  • @AnimeshSahu it will post to the UI only if you call runOnUiThread, am I wrong? – Dan Baruch Nov 17 '20 at 13:27
  • 1
    @DanBaruch A handler is associated with the thread it is created according to [as mentioned in this answer](https://stackoverflow.com/a/18713584/11377112). And this is better explaination: https://stackoverflow.com/a/15136250/11377112 – Animesh Sahu Nov 17 '20 at 13:29
  • I find it quite odd as I've been using thread.sleep a lot in handlers and my UI was still active. I'll check it and update back. You do see that I use new Runnable there, yes? Edit: I just checked it, you are indeed correct. That's good to know. Thanks @AnimeshSahu – Dan Baruch Nov 17 '20 at 13:30

1 Answers1

1

I believe what happens is that because you are running this long running task in the main thread, the UI fails to update directly. Try running the loop in a coroutine scope, so that it does not block the UI from updating. I used the following code, and the button was disabled directly:

fun calc(){
    clickableButton.isEnabled = false

    lifecycleScope.launch {
        withContext(Dispatchers.Default){
            for (x in 0 until 100000) {
                Log.d("calc: ","$x")
            }
        }
    }
}
M. Abdel-Ghani
  • 187
  • 1
  • 10