Lag when processing pointer position during onTouch MotionEvent Android Kotlin

47 Views Asked by At

I'm creating a custom view to draw a candlestick chart. It reads values from multi-touch pointer positions in the view's onTouch event to calculate the distance between the two pointers and zoom in or out. I've opted to use this method as opposed to gesture detection because it gives me more fine control over the calculations, allowing me to process changes in the X and Y axis separately (which is required for my chart to function).

This is where it gets strange - There seems to be a lag in the two finger zoom portion of it specifically:

Zooming in one direction and releasing works fine, but if you change direction during the same drag event there's an overshoot, where despite you starting to zoom the other way it keeps moving as it was before for a few event steps before gradually correcting and then catching up to your fingers. This makes zooming possible, but a little bit “spongy” and unreactive.

What am I missing here?

Snippet from onTouch event:

if(event.action == MotionEvent.ACTION_MOVE && event.pointerCount == 2){ 
    val touchA = PointF(
        event.getX(0),
        event.getY(0)
    )
    val touchB = PointF(
        event.getX(1),
        event.getY(1)
    )
        if (trackingZoom) {
            val zoomDistanceHChange = (startZoomHDistance - abs(touchA.x - touchB.x)) * ptPerPX(Orientation.HORIZONTAL)
            val zoomDistanceVChange = (startZoomVDistance - abs(touchA.y - touchB.y)) * ptPerPX(Orientation.VERTICAL)
           // ^^ Translates touch position into chart units so that things move the correct distance relative to your finger.

            moveView(startZoomViewRect.left - zoomDistanceHChange/2F, startZoomViewRect.top - zoomDistanceVChange/2F, startZoomViewRect.width() + zoomDistanceHChange, startZoomViewRect.height() + zoomDistanceVChange)
            // ^^ Moves and rescales the chart, drawing the changes to the view.

        }else{
            startZoomViewRect = viewRect
            // ^^ viewRect is a RectF instance describing the currently viewed area of the chart.

            startZoomHDistance = abs(touchA.x - touchB.x)
            startZoomVDistance = abs(touchA.y - touchB.y)
            trackingZoom = true
        }
}

As far as I can tell the documentation suggests that event.getX should return the most up to date pointer positions, so it's not clear to me where this lag is being introduced. What's also interesting is that tracking the position of a single touch event for panning works flawlessly.

Any pointers you can give me would be really welcome.

0

There are 0 best solutions below