Scale 및 Gesture Handler
17 Aug 2019 | Android화면의 TouchEvent에서 멀티 터치를 이용한 Scale이나 Gesture를 인식하는 Handler 코드 예제입니다.
package com.snowdeer.utils
import android.content.Context
import android.view.GestureDetector
import android.view.MotionEvent
import android.view.ScaleGestureDetector
interface OnScaleGestureEventListener {
fun onSingleTab(x: Float, y: Float)
fun onDoubleTab(x: Float, y: Float)
fun onLongPress(x: Float, y: Float)
fun onScaleChanged(scaleFactor: Float)
fun onOffsetChanged(offsetX: Float, offsetY: Float)
}
class ScaleGestureHandler(ctx: Context) {
private var scaleFactor = 1.0F
private var offsetX = 0.0F
private var offsetY = 0.0F
private var scaledOffsetX = 0.0F
private var scaledOffsetY = 0.0F
private var focusX = 0.0F
private var focusY = 0.0F
private val scaleGestureDetector: ScaleGestureDetector
private val gestureDetector: GestureDetector
var onScaleGestureEventListener: OnScaleGestureEventListener? = null
init {
scaleGestureDetector = ScaleGestureDetector(ctx, ScaleListener())
gestureDetector = GestureDetector(ctx, GestureListener())
}
fun handleTouchEvent(event: MotionEvent): Boolean {
scaleGestureDetector.onTouchEvent(event)
if (gestureDetector.onTouchEvent(event)) {
return true
}
return false
}
fun reset() {
scaleFactor = 1.0F
offsetX = 0F
offsetY = 0F
scaledOffsetX = 0F
scaledOffsetY = 0F
focusX = 0.0F
focusY = 0.0F
}
private inner class ScaleListener : ScaleGestureDetector.SimpleOnScaleGestureListener() {
override fun onScale(detector: ScaleGestureDetector): Boolean {
scaleFactor *= detector.scaleFactor
scaleFactor = Math.max(0.8f, Math.min(scaleFactor, 3.0f))
focusX = detector.focusX
focusY = detector.focusY
onScaleGestureEventListener?.onScaleChanged(scaleFactor)
offsetX = (scaledOffsetX - focusX) * scaleFactor + focusX
offsetY = (scaledOffsetY - focusY) * scaleFactor + focusY
onScaleGestureEventListener?.onOffsetChanged(offsetX, offsetY)
return true
}
}
private inner class GestureListener : GestureDetector.SimpleOnGestureListener() {
override fun onSingleTapConfirmed(e: MotionEvent): Boolean {
onScaleGestureEventListener?.onSingleTab(e.x, e.y)
return true
}
override fun onDoubleTap(e: MotionEvent): Boolean {
onScaleGestureEventListener?.onDoubleTab(e.x, e.y)
return true
}
override fun onLongPress(e: MotionEvent) {
onScaleGestureEventListener?.onLongPress(e.x, e.y)
}
override fun onScroll(e1: MotionEvent, e2: MotionEvent, distanceX: Float, distanceY: Float): Boolean {
scaledOffsetX -= distanceX / scaleFactor
scaledOffsetY -= distanceY / scaleFactor
offsetX = (scaledOffsetX - focusX) * scaleFactor + focusX
offsetY = (scaledOffsetY - focusY) * scaleFactor + focusY
onScaleGestureEventListener?.onOffsetChanged(offsetX, offsetY)
return true
}
}
}