Home > Software engineering >  Kotlin - press a button 1 time, show messages several times in TextView
Kotlin - press a button 1 time, show messages several times in TextView

Time:09-13

How to implement showing several messages in a TextView field one by one with a required delay by clicking button only one time?

I tried this (look at the code below) and got such a result: three seconds go by and only "3" is shown in the end. Digits 1 and 2 aren't shown.

class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    binding = ActivityMainBinding.inflate(layoutInflater)
    setContentView(binding.root)

    binding.button.setOnClickListener {test()}
}

fun test() {
    for (i in (1..3)){
        binding.text1.text = "${i}"
        Thread.sleep(1000L)
    }
}

}

CodePudding user response:

You really shouldn't sleep Main Thread. Main thread is used to display UI by sleeping it you are blocking the whole UI and that is why it is not updating. You can use Timer to run code every second

new Timer().scheduleAtFixedRate(new TimerTask() {
  @Override
  public void run() {
    //your method
  }
}, 0, 1000);//1 second

So for example you can start timer on button click and stop it after 3 seconds

CodePudding user response:

Thanks for the tip about Timer.

This thread helped me further. How to create a simple countdown timer in Kotlin?

Now my code looks like this and it works and does what I wanted:

fun test() {
    var cnt = 3
    val timer = object: CountDownTimer(3000, 1000) {
        override fun onTick(millisUntilFinished: Long) {
            binding.text1.text = cnt.toString()
            cnt--
        }
        override fun onFinish() {
            binding.text1.text = "That's it"
        }
    }
    timer.start()
}

CodePudding user response:

Sleeping the main thread isn't solution for such simple task you should use concurrency like the code below using corouties

suspend fun test(){
     for(i in (1..3) {
         delay(1000L)
         binding.text1.text = i.toStrong()
     }
}

And invokeOnCompletion {} is pretty good callback to handle completion

  • Related