У меня есть кнопки плюс и минус, которые работают при нажатии. Теперь я хочу сделать их, когда вы удерживаете / нажимаете их, они перемещаются вверх / вниз более чем по 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
}
для этого вам нужно реализовать обработчик или CountDownTimer
У вас есть пример этого?
попробуйте отредактированный код...
Вот вспомогательный класс и функция для этого, которые позволяют вам делать все, что вы хотите, пока кнопка удерживается нажатой:
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 для этого. В остальном все работало нормально.
Когда я удерживаю, он увеличивается только на 1. Я хочу, чтобы он увеличивался на 1 в секунду, если вы понимаете, что я имею в виду.