Search code examples
androidkotlin

For loop doesn't refresh name in the UI


In Android (Kotlin), I am doing a for loop to solve the problem of finding an exact word and I want to show the words calculated and the iteration number in a TextView, but the word and numbers are only showed once the for loop has finished and not over the calculation.

private fun buscaPaco(){

    for (i in 1..1000000) {
        tamañoABC = abc.size - 1
        ordenLetra01 = (0..tamañoABC).random()
        ordenLetra02 = (0..tamañoABC).random()
        ordenLetra03 = (0..tamañoABC).random()
        ordenLetra04 = (0..tamañoABC).random()
        abcLetra01 = abc[ordenLetra01]
        abcLetra02 = abc[ordenLetra02]
        abcLetra03 = abc[ordenLetra03]
        abcLetra04 = abc[ordenLetra04]

        palabra02 = abcLetra01 + abcLetra02 + abcLetra03 + abcLetra04
        tvPalabras.text = palabra02

        if (palabra01 == palabra02){
            tvEncontrado.text = palabra01 + " encontrado. Iteración: " + i.toString()
            tvEncontrado.setBackgroundResource(R.color.red)
            break
        }
        else{
            tvEncontrado.text = "buscando, iteración: " + i.toString()
        }

        factor1To100 = i/factor100
        factorInt = factor1To100.toInt()
        escribirProgreso()

    }

}

Solution

  • You are doing calculations (heavy task) on the Main UI thread. So it freezes the UI until your loop finished. To solve this problem, you can do calculations in the background and update results on the main UI thread. You can use Thread, Kotlin coroutines or Java concurrent for that.

    Here is an example of using coroutines.

    private fun buscaPaco() {
        val job = lifecycleScope.launch {
            for (i in 1..1000000) {
                // do some calculations in the background ..
                palabra02 = ...
    
                launch(Dispatchers.Main) {
                    // update UI in Main thread
                    tvPalabras.text = palabra02
                    // ...
                    escribirProgreso() // also update progress in Main thread
                }
    
                // ...
                // You can also set delay between each calculations using delay()
                delay(100)
            }
        }
    
        // you can cancel the job at any time using job.cancel()
    }