Home > front end >  Is it possible to keep a button's label alternating between values until it is clicked?
Is it possible to keep a button's label alternating between values until it is clicked?

Time:07-29

For example, a button would be labeled with digits from 0 to 9, one at a time and changing at a given rate (say, each half a second). When clicked, the label would stop changing and be set to the value showing at the time. Is there any way to do this?

CodePudding user response:

Yes, this is possible. You could use a Handler (Java) or a coroutine (Kotlin) to do this. Here are some examples:

Kotlin

With Kotlin, you can start a coroutine that has a loop with a delay, and when the button is clicked it exits the loop and stops updating the button text and stored number.

private lateinit var binding: ActivityMainBinding

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding = ActivityMainBinding.inflate(layoutInflater)
    setContentView(binding.root)

    binding.timedBtn.setOnClickListener { incrementing = false }
    startNumbers()
}

private var incrementing = true
private var num = 0
private val delayMillisecond = 500L

private fun startNumbers() {
    incrementing = true
    lifecycleScope.launch {
        while(incrementing) {
            num = (num   1) % 10
            binding.timedBtn.text = "$num"
            delay(delayMillisecond)
        }
    }
}

Java

With Java you can use a handler and postDelayed to keep posting future updates to the button text, and when the button is pressed cancel all the handler tasks so it stops updating the button text and stored number.

private ActivityMainBinding binding;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    binding = ActivityMainBinding.inflate(getLayoutInflater());
    setContentView(binding.getRoot());
    
    binding.timedBtn.setOnClickListener(v -> handler.removeCallbacksAndMessages(null));
    startNumbers();
}

private final Handler handler = new Handler();
private int num = 0;
private final long delay_ms = 500;

private void startNumbers() {
    handler.post(new Runnable() {
        @Override
        public void run() {
            num = (num   1) % 10;
            binding.timedBtn.setText(String.valueOf(num));
            handler.postDelayed(this, delay_ms);
        }
    });
}

  • Related