Home > Software engineering >  Increase value of text when button is hold
Increase value of text when button is hold

Time:04-05

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.

CodePudding user response:

try below code may help

plusBtn.setOnTouchListener { _, event ->
    if (event.action == MotionEvent.ACTION_DOWN) {
         // button pressed

           object : CountDownTimer(99000, 1000) {

              override fun onTick(millisUntilFinished: Long) { 
                   val temp = 99000 - (millisUntilFinished / 1000)
                   PenaltyTimeInputTxt.setText("" temp)
               }

               override fun onFinish() {
                   Toast.makeText(this, "Penalty time cannot go over 99", Toast.LENGTH_SHORT).show()
               }
           }.start()

         
    }
    if (event.action == MotionEvent.ACTION_UP) {
         // button released
       
    }
    true
}

CodePudding user response:

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 {
        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())
        }
        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
    }
}
  • Related