I am trying to handle touch events and click events on a button. I do the following:
button.setOnClickListener(clickListener);
button.setOnTouchListener(touc
This is an example of TouchListener that doesn't shadow ClickListener.
import android.graphics.PointF
import android.view.MotionEvent
import android.view.MotionEvent.*
import android.view.View
import kotlin.math.abs
object TouchAndClickListener : View.OnTouchListener {
/** Those are factors you can change as you prefer */
private const val touchMoveFactor = 10
private const val touchTimeFactor = 200
private var actionDownPoint = PointF(0f, 0f)
private var previousPoint = PointF(0f, 0f)
private var touchDownTime = 0L
override fun onTouch(v: View, event: MotionEvent) = when (event.action) {
ACTION_DOWN -> PointF(event.x, event.y).let {
actionDownPoint = it // Store it to compare position when ACTION_UP
previousPoint = it // Store it to compare position when ACTION_MOVE
touchDownTime = now() // Store it to compare time when ACTION_UP
/* Do other stuff related to ACTION_DOWN you may whant here */
true
}
ACTION_UP -> PointF(event.x, event.y).let {
val isTouchDuration = now() - touchDownTime < touchTimeFactor // short time should mean this is a click
val isTouchLength = abs(it.x - actionDownPoint.x) + abs(it.y - actionDownPoint.y) < touchMoveFactor // short length should mean this is a click
val shouldClick = isTouchLength && isTouchDuration // Check both
if (shouldClick) yourView.performClick() //Previously define setOnClickListener{ } on yourView, then performClick() will call it
/* Do other stuff related to ACTION_UP you may whant here */
true
}
ACTION_MOVE -> PointF(event.x, event.y).let {
/* Do other stuff related to ACTION_MOVE you may whant here */
previousPoint = it
true
}
else -> false // Nothing particular with other event
}
private fun now() = System.currentTimeMillis()
}