Search code examples
android-studiokotlingoogle-mapspolyline

is there a way i can animate a polyline?


Something similar to a pulsing ring around a marker. What I want to achieve is this... I have many polylines all having Lat/Lng. At a time t, a user can decide to pick any polyline of their choosing. I get their current real-time location coordinates via Bluetooth. I want to use that location to determine how far they are from the polyline they have selected and depending on the distance, change/animate that polyline. I am using google maps API, android studio, kotlin


Solution

  • Here's a simple example - a method which takes a Polyline instance and a handler (must be on main looper) and begins a repeating update to the polyline width.

    (Added the Kotlin)

    private lateinit var polyline: Polyline;
    private lateinit var handler : Handler;
    
    override fun onMapReady(googleMap: GoogleMap) {
        mMap = googleMap
    
        var ptlist = ArrayList<LatLng>();
    
        // add polyline
        ptlist.add(LatLng(40.437761, -3.704751));
        ptlist.add(LatLng( 40.405072, -3.678678));
        ptlist.add(LatLng( 40.397158, -3.742706));
        ptlist.add(LatLng(40.437761, -3.704751));
    
        handler = Handler(Looper.getMainLooper());
    
        polyline = mMap.addPolyline(PolylineOptions().addAll(ptlist));
    
        val runnableCode = object: Runnable {
            override fun run() {
                var w = polyline.width;
                w = w + 0.5f;
                if (w > 25.0) {
                    w = 1.0f;
                }
                polyline.setWidth(w);
                handler.postDelayed(this, 50);
            }
        }
    
        mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(40.415521, -3.700995), 12f));
        handler.postDelayed(runnableCode, 50);
    
    }
    

    In this example, the witdh of polyline p will vary from [25.0 1.0] incrementing by 0.5 every 200 milliseconds. When it reaches the maximum width it is reset to a width of 1.0. The original width is ignored.

    Obviously change the parameters as needed - or make it pulse in and out.

    Demo

    (Java equivalent - animation parameters different.)

    public void pulsePolyline(final Polyline p, final Handler h)
    {
        h.postDelayed(new Runnable() {
            @Override
            public void run() {
    
                float w = p.getWidth();
                w = (w + 0.1);
                if (w > 10.0) w = 1.0;
                p.setWidth(w);
                h.postDelayed(this, 200);
            }
       }, 200);
    }
    

    Note the handler must be from the main thread (or looper) as in:

    new Handler(Looper.getMainLooper())