androidgoogle-mapsandroid-maps-v2

Replace default Android Maps API v2 Change MyLocation icon


I would like to replace the default icon that Android Maps V2 uses for 'My Location' with my own image. I've created my own tile provider that brings in a few maps which are predominantly blue and as such the default My Location icon, the little blue arrow, is very hard to see.

Previously I would have just overridden the draw method of the MyLocationOverlay, but there doesn't seem to be one in the new API.

I also need the icon to be able to rotate, the same way that the arrow does depending on which way you are facing. So I can't just use a normal marker. Basically I just need to create a custom image for that arrow.


Solution

  • The latest update to Google Play Services now allows you to use 'Flat' Markers and rotate them which is exactly what I needed. Here is a simple version of the way I implemented it. There is probably a fair bit I can do to optimize and tweak the animation, but it does the job for the moment. Any feedback is welcome.

    Marker mPositionMarker;
    GoogleMap mMap;
    
    @Override
    public void onLocationChanged(Location location) {
    
        if (location == null)
            return;
    
        if (mPositionMarker == null) {
    
            mPositionMarker = mMap.addMarker(new MarkerOptions()
                    .flat(true)
                    .icon(BitmapDescriptorFactory
                            .fromResource(R.drawable.positionIndicator))
                    .anchor(0.5f, 0.5f)
                    .position(
                            new LatLng(location.getLatitude(), location
                                    .getLongitude())));
        }
    
        animateMarker(mPositionMarker, location); // Helper method for smooth
                                                    // animation
    
        mMap.animateCamera(CameraUpdateFactory.newLatLng(new LatLng(location
                .getLatitude(), location.getLongitude())));
    
    }
    
    public void animateMarker(final Marker marker, final Location location) {
        final Handler handler = new Handler();
        final long start = SystemClock.uptimeMillis();
        final LatLng startLatLng = marker.getPosition();
        final double startRotation = marker.getRotation();
        final long duration = 500;
    
        final Interpolator interpolator = new LinearInterpolator();
    
        handler.post(new Runnable() {
            @Override
            public void run() {
                long elapsed = SystemClock.uptimeMillis() - start;
                float t = interpolator.getInterpolation((float) elapsed
                        / duration);
    
                double lng = t * location.getLongitude() + (1 - t)
                        * startLatLng.longitude;
                double lat = t * location.getLatitude() + (1 - t)
                        * startLatLng.latitude;
    
                float rotation = (float) (t * location.getBearing() + (1 - t)
                        * startRotation);
    
                marker.setPosition(new LatLng(lat, lng));
                marker.setRotation(rotation);
    
                if (t < 1.0) {
                    // Post again 16ms later.
                    handler.postDelayed(this, 16);
                }
            }
        });
    }