按住按钮时增加文本的值

Increase value of text when button is hold

我有一个加号和减号按钮,按下时可以使用。现在我想在你 hold/press 下来的时候制作它们,一次 up/down 多于 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)
        }
    }

试试下面的代码可能会有帮助

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
}

这里有一个助手 class 和函数,它可以让您在按住按钮时做任何您想做的事情:

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

它运行的协程会在您每次单击并按住时重新启动。它还会停止协程并在您拖离按钮然后重新打开时重新启动协程,这是一种传统的 UI 行为。

要将其用于您的行为,您可以使用 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
    }
}