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);
}
});
}