Увеличить значение текста при удержании кнопки

У меня есть кнопки плюс и минус, которые работают при нажатии. Теперь я хочу сделать их, когда вы удерживаете / нажимаете их, они перемещаются вверх / вниз более чем по 1 за раз.

Это одна из моих обычных кнопок:

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

есть ли простой способ сделать это? Я видел кое-что о onTouchListener.

РЕДАКТИРОВАТЬ --- Конечный результат. Спасибо Tenfour04: включите все самое интересное view.doWhileHeld + это:

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)
        }
    }
0
0
49
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

попробуйте код ниже может помочь

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
}

Когда я удерживаю, он увеличивается только на 1. Я хочу, чтобы он увеличивался на 1 в секунду, если вы понимаете, что я имею в виду.

masterturner96 05.04.2022 12:42

для этого вам нужно реализовать обработчик или CountDownTimer

OmiK 05.04.2022 13:08

У вас есть пример этого?

masterturner96 05.04.2022 13:10

попробуйте отредактированный код...

OmiK 05.04.2022 13:17
Ответ принят как подходящий

Вот вспомогательный класс и функция для этого, которые позволяют вам делать все, что вы хотите, пока кнопка удерживается нажатой:

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

Он запускает сопрограмму, которая перезапускается каждый раз, когда вы нажимаете и удерживаете. Он также останавливает сопрограмму и перезапускает ее, если вы перетаскиваете кнопку, а затем снова нажимаете ее, что является обычным поведением пользовательского интерфейса.

Чтобы использовать его для своего поведения, вы можете использовать цикл while:

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

Спасибо, мне пришлось изменить viewLifecycleowner для этого. В остальном все работало нормально.

masterturner96 06.04.2022 10:35

Другие вопросы по теме

Похожие вопросы