How to detect the pinch-zoom event with OnGestureListener in Android?
Asked Answered
I

3

19

How to detect the pinch-zoom event with OnGestureListener in Android?

Ibnsina answered 18/4, 2011 at 16:27 Comment(0)
O
30

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.

Outpatient answered 18/4, 2011 at 17:11 Comment(1)
Please make sure your answer will work after they take down the blog.Amperage
R
1

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
}

}

Rayner answered 23/9, 2021 at 7:35 Comment(0)
H
1

You can achieve this in 3 easy steps:

  1. 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) { }
    }
    
  2. Create ScaleGestureDetector object

     scaleGestureDetector = ScaleGestureDetector(this, 
       CustomOnScaleGestureListener())
    
  3. 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) { }
}


}
Hetzel answered 11/10, 2021 at 18:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.