How to make a button click cumulative?

105 Views Asked by At

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

2

There are 2 best solutions below

0
On BEST ANSWER

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)
        }
    }
}
3
On

do you have any option in map framework for stopping current animation (e.g. move)?

if you have then just call it at the begining of click method

if not then imho this is a proper solution to introduce some variable lastClicked = System.currentTimeMillis() and checking if (System.currentTimeMillis() - lastClicked < 500) return at the begining of onClick