I have a plus and min button that work when pressed. Now I want to make them when you hold/press it down it goes up/down more then 1 at a time.
This is one of my regular buttons:
plusBtn.setOnClickListener {
if(isEmpty(PenaltyTimeInputTxt.text))
{
PenaltyTimeInputTxt.setText("0")
}
penaltyInput = PenaltyTimeInputTxt.text.toString().toInt()
if(penaltyInput < 99){
penaltyInput++
PenaltyTimeInputTxt.setText(penaltyInput.toString())
}
else {
Toast.makeText(this, "Penalty time cannot go over 99", Toast.LENGTH_SHORT).show()
}
}
is there a simple way of doing this? I saw something about onTouchListener.
EDIT --- End result. Thanks to Tenfour04: include the whole fun view.doWhileHeld + this:
plusBtn.doWhileHeld(this.lifecycleScope) {
if(isEmpty(PenaltyTimeInputTxt.text)) {
PenaltyTimeInputTxt.setText("0")
}
penaltyInput = PenaltyTimeInputTxt.text.toString().toInt()
while (isActive) {
if(penaltyInput < 99) {
penaltyInput++
PenaltyTimeInputTxt.setText(penaltyInput.toString())
}
else {
Toast.makeText(this@PenaltyConfigureActivity, "Penalty time cannot go over 99", Toast.LENGTH_SHORT).show()
break
}
delay(200)
}
}
Here is a helper class and function for this, which lets you do whatever you want while the button is held down:
fun View.doWhileHeld(
coroutineScope: CoroutineScope,
block: suspend CoroutineScope.() -> Unit
) = setOnTouchListener(object : View.OnTouchListener {
var job: Job? = null
var pointerInBounds = false
@SuppressLint("ClickableViewAccessibility")
override fun onTouch(view: View, event: MotionEvent): Boolean {
if (!isEnabled) {
job?.cancel()
return false
}
when (event.action) {
MotionEvent.ACTION_DOWN -> {
job = coroutineScope.launch(block = block)
pointerInBounds = true
}
MotionEvent.ACTION_MOVE -> {
val movedInBounds = event.x.roundToInt() in 0..view.width
&& event.y.roundToInt() in 0..view.height
if (pointerInBounds != movedInBounds) {
pointerInBounds = movedInBounds
if (pointerInBounds) {
job = coroutineScope.launch(block = block)
} else {
job?.cancel()
}
}
}
MotionEvent.ACTION_UP -> {
job?.cancel()
}
}
return false // allow click interactions
}
})
It runs a coroutine that restarts every time you click and hold. It also stops the coroutine and restarts it if you drag off the button and then back on, which is a conventional UI behavior.
To use it for your behavior, you can use a while
loop:
plusBtn.doWhileHeld(viewLifecycleOwner.lifecycleScope) {
if(isEmpty(PenaltyTimeInputTxt.text)) {
PenaltyTimeInputTxt.setText("0")
}
penaltyInput = PenaltyTimeInputTxt.text.toString().toInt()
while (isActive) {
if(penaltyInput < 99) {
penaltyInput++
PenaltyTimeInputTxt.setText(penaltyInput.toString())
if (penaltyInput == 99) { // optional, might be nicer than showing toast
plusBtn.isEnabled = false
break
}
}
else {
Toast.makeText(this, "Penalty time cannot go over 99", Toast.LENGTH_SHORT).show()
break
}
delay(500) // adjust for how fast to increment the value
}
}