How to detect the pinch-zoom event with OnGestureListener in Android?
How to detect the pinch-zoom event with OnGestureListener in Android?
Take a look at this post on the Android Developers blog: http://android-developers.blogspot.com/2010/06/making-sense-of-multitouch.html
The later sections talk about using ScaleGestureDetector with code examples.
Please make sure your answer will work after they take down the blog. –
Amperage
A simple example in Kotlin, using the referred blog in adamp's answer.
class CustomView @JvmOverloads constructor (context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0): View(context, attrs, defStyleAttr), View.OnTouchListener {
private var scaleFactor = 1f
private val scaleDetector: ScaleGestureDetector =
ScaleGestureDetector(context, object: ScaleGestureDetector.SimpleOnScaleGestureListener(){
override fun onScale(detector: ScaleGestureDetector?): Boolean {
detector?.let {
scaleFactor *= it.scaleFactor
scaleFactor = scaleFactor.coerceIn(0.5f, 5f)
//scale your view
invalidate()
}
return super.onScale(detector)
}
})
init {
setOnTouchListener(this)
}
private var lastTouchX = 0F
private var lastTouchY = 0F
override fun onTouch(v: View?, event: MotionEvent?): Boolean {
scaleDetector.onTouchEvent(event)
event?.let { motionEvent ->
when (motionEvent.action) {
MotionEvent.ACTION_DOWN -> {
lastTouchX = motionEvent.x
lastTouchY = motionEvent.y
}
MotionEvent.ACTION_MOVE -> {
if (!scaleDetector.isInProgress) {
val dX = motionEvent.x - lastTouchX
val dY = motionEvent.y - lastTouchY
// offset your objects with (dX, dY)
invalidate()
}
}
}
}
return true
}
}
You can achieve this in 3 easy steps:
Create SimpleOnScaleGestureListener class like this:
class CustomOnScaleGestureListener : ScaleGestureDetector.SimpleOnScaleGestureListener() { override fun onScale(detector: ScaleGestureDetector): Boolean { val scaleFactor = detector.scaleFactor if (scaleFactor > 1) { // Zooming Out } else { // Zooming In } return true } override fun onScaleBegin(detector: ScaleGestureDetector): Boolean { return true } override fun onScaleEnd(detector: ScaleGestureDetector) { } }
Create ScaleGestureDetector object
scaleGestureDetector = ScaleGestureDetector(this, CustomOnScaleGestureListener())
Override onTouchEvent in your activity
override fun onTouchEvent(event: MotionEvent): Boolean { scaleGestureDetector?.onTouchEvent(event) return true }
Full Example:
class MainActivity : AppCompatActivity(){
private lateinit var mBinding: ActivityMainBinding
var scaleGestureDetector: ScaleGestureDetector? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mBinding = ActivityMainBinding.inflate(layoutInflater)
setContentView(mBinding.root)
scaleGestureDetector = ScaleGestureDetector(this, CustomOnScaleGestureListener())
}
override fun onTouchEvent(event: MotionEvent): Boolean {
scaleGestureDetector?.onTouchEvent(event)
return true
}
inner class CustomOnScaleGestureListener : ScaleGestureDetector.SimpleOnScaleGestureListener() {
override fun onScale(detector: ScaleGestureDetector): Boolean {
val scaleFactor = detector.scaleFactor
if (scaleFactor > 1) {
// Zooming Out
} else {
// Zooming In
}
return true
}
override fun onScaleBegin(detector: ScaleGestureDetector): Boolean {
return true
}
override fun onScaleEnd(detector: ScaleGestureDetector) { }
}
}
© 2022 - 2024 — McMap. All rights reserved.