androidkotlinyandex-mapkit

How to make a button click cumulative?


I have a listener for my map zoom buttons:

class ZoomMapListener(
    mapView: MapView,
    private val zoom: Zoom
) : View.OnClickListener {

    private val localMapView = WeakReference(mapView)
    //private var clickCounter = 0

    override fun onClick(view: View?) {
        //clickCounter++
        localMapView.get()?.let {
            var cameraPosition = it.map.cameraPosition

            val zoom = if (zoom == IN) {
                cameraPosition.zoom + 1.0f
                //cameraPosition.zoom + (clickCounter * 1.0f)
            } else {
                cameraPosition.zoom - 1.0f
                //cameraPosition.zoom - (clickCounter * 1.0f)
            }

            cameraPosition = CameraPosition(
                cameraPosition.target,
                zoom,
                cameraPosition.azimuth,
                cameraPosition.tilt
            )

            it.map.move(cameraPosition, Animation(Animation.Type.SMOOTH, 0.5f), null)
        }
    }
}

I'm setting it like this:

zoomInMapButton.setOnClickListener(ZoomMapListener(mapView, Zoom.IN))
zoomOutMapButton.setOnClickListener(ZoomMapListener(mapView, Zoom.OUT))

But the problem is that if user is clicking on one of this buttons multiple times map is not zooming properly, because of the animation: user clicked the button -> camera position is moving for 0.5s -> in less than 0.5s user is clicking the second/third/etc. time and onClick method is taking the intermediate camera position. Because of that the behavior of zooming varies in different cases.

Because I don't want to set animation duration to zero, I've been thinking that I can make a variable to save up this click counting(it is commented in the code above), but it is not the right way, so I'm stuck


Solution

  • I think your approach is right. Just make a few changes

    class ZoomMapListener(
        mapView: MapView,
        private val zoom: Zoom
    ) : View.OnClickListener {
    
        private val localMapView = WeakReference(mapView)
        private var clickCounter = 0
    
        override fun onClick(view: View?) {
            clickCounter++
            if(clickCounter>1) return
            setZoom()
        }
    
        setZoom() {
            localMapView.get()?.let {
                var cameraPosition = it.map.cameraPosition
    
                val zoom = if (zoom == IN) {
                    cameraPosition.zoom + 1.0f
                    //cameraPosition.zoom + (clickCounter * 1.0f)
                } else {
                    cameraPosition.zoom - 1.0f
                    //cameraPosition.zoom - (clickCounter * 1.0f)
                }
    
                cameraPosition = CameraPosition(
                    cameraPosition.target,
                    zoom,
                    cameraPosition.azimuth,
                    cameraPosition.tilt
                )
    
                it.map.move(cameraPosition, Animation(Animation.Type.SMOOTH, 0.5f), null)
                clickCounter--;
                Handler().postDelayed({
                    if(counter>0) setZoom()
                }, 550)
            }
        }
    }