Search code examples
androidgoogle-mapsandroid-animationgoogle-polyline

Animation not working fine with polyline?


I am creating the polyline with animation & in onLocationChanged() polyline is being created. Every time when onLocationChanged() called, a new polyline is created.

Note: Animation is like: first black color line will move to source to destination with animation and then grey color line. The problem is, it works fine for sometimes. But after sometime black line is not visible only grey line animation is showing.

For reference, please see the attached file. In gif you can see that it worked fine for first four times and after that you can notice, black line is not visible. It is invisible because it is behind the grey line.

enter image description here

This is my onLocationChanged() method:

    @Override
    public void onLocationChanged(final Location location) {
        super.onLocationChanged(location);
        mLat = location.getLatitude();
        mLng = location.getLongitude();

        LatLng myLatLngCurrentONlocationChnage = new LatLng(mLat, mLng);

        if (btnYesBooking || isBookingReserve) {
            mSearchComplete.setVisibility(View.GONE);
            String url = getDirectionsUrl(myLatLngCurrentONlocationChnage, myLatLngFinalDestinationClicked);

            DownloadTask downloadTask = new DownloadTask();

            // Start downloading json data from Google Directions API
            downloadTask.execute(url);

            myDestinationBookingMarker = mGoogleMap.addMarker(new MarkerOptions()
                    .position(myLatLngFinalDestinationClicked)
                    .icon(BitmapDescriptorFactory.fromResource(R.drawable.red_pin)));
            addMarker(mGoogleMapCar, mLat, mLng);
}

Please have a look into the onPostExecute() method where animation code is implemented.

        @Override
        protected void onPostExecute(List<List<HashMap<String, String>>> result) {

            PolylineOptions lineOptions = null;
            if (result != null) {
                // Traversing through all the routes
                for (int i = 0; i < result.size(); i++) {
                    points = new ArrayList<LatLng>();
                    lineOptions = new PolylineOptions();

                    // Fetching i-th route
                    final List<HashMap<String, String>> path = result.get(i);

                    // Fetching all the points in i-th route
                    for (int j = 0; j < path.size(); j++) {
                        HashMap<String, String> point = path.get(j);
                        if (j == 0) {    // Get distance from the list
                            estimateDistance = (String) point.get("distance");

                            continue;
                        } else if (j == 1) { // Get duration from the list
                            estimeteDuration = (String) point.get("duration");
                            continue;
                        }

                        double lat = Double.parseDouble(point.get("lat"));
                        double lng = Double.parseDouble(point.get("lng"));
                        LatLng position = new LatLng(lat, lng);
                        // points.clear();
                        points.add(position);
                    }


                    if (estimeteDuration != null) {
                        mTvEstimatedTime.setText("Estimated Time to reach: " + estimeteDuration);
                        mSearchComplete.setVisibility(View.GONE);
                        mTxtEstimateArrivalTime.setText(estimeteDuration);


                    }
                    mTvEstimatedTime.setVisibility(View.VISIBLE);
                    mTxtEstimateArrivalTime.setVisibility(View.VISIBLE);
                    mRecyclerViewHotspot.setVisibility(View.GONE);
                    mDetailLayout.setVisibility(View.GONE);
                    mParkingdetailLayout.setVisibility(View.GONE);

                    lineOptions.addAll(points);
                }

                LatLngBounds.Builder builder = new LatLngBounds.Builder();
                for (LatLng latLng : points) {
                    builder.include(latLng);
                }
                polylineOptions = new PolylineOptions();
                polylineOptions.color(Color.GRAY);
                polylineOptions.width(12);
                polylineOptions.startCap(new SquareCap());
                polylineOptions.endCap(new SquareCap());
                polylineOptions.jointType(ROUND);
                polylineOptions.addAll(points);
                greyPolyLine = mGoogleMap.addPolyline(polylineOptions);

                blackPolylineOptions = new PolylineOptions();
                blackPolylineOptions.width(12);
                blackPolylineOptions.color(Color.BLACK);
                blackPolylineOptions.startCap(new SquareCap());
                blackPolylineOptions.endCap(new SquareCap());
                blackPolylineOptions.jointType(ROUND);

                blackPolyline = mGoogleMap.addPolyline(blackPolylineOptions);
                polylineAnimator = ValueAnimator.ofInt(0, 100);
                polylineAnimator.setDuration(700);
                polylineAnimator.setInterpolator(new LinearInterpolator());
                polylineAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator valueAnimator) {

                        List<LatLng> points = greyPolyLine.getPoints();
                        int percentValue = (int) valueAnimator.getAnimatedValue();
                        int size = points.size();
                        int newPoints = (int) (size * (percentValue / 100.0f));
                        List<LatLng> p = points.subList(0, newPoints);
                        blackPolyline.setPoints(p);


                    }
                });


                polylineAnimator.addListener(new Animator.AnimatorListener() {
                    @Override
                    public void onAnimationStart(Animator animation) {

                    }

                    @Override
                    public void onAnimationEnd(Animator animation) {
                        List<LatLng> greyLatLng = greyPolyLine.getPoints();
                        if (greyLatLng != null) {
                            greyLatLng.clear();

                        }
                        polylineAnimator.start();

                    }

                    @Override
                    public void onAnimationCancel(Animator animation) {
                        polylineAnimator.cancel();
                    }

                    @Override
                    public void onAnimationRepeat(Animator animation) {

                    }
                });

                polylineAnimator.start();


            }
            mGoogleMap.getUiSettings().setZoomGesturesEnabled(false);
            zoomRoute(mGoogleMap, points);

        }

Any idea what I am doing wrong? Thanks!


Solution

  • You can set the zIndex for your black line to ensure that is drawn over the grey line.

    As stated in the documentation:

    An overlay with a larger z-index is drawn over overlays with smaller z-indices. The order of overlays with the same z-index is arbitrary. The default zIndex is 0.

    You can set the zIndex of your line using your blackPolylineOptions object:

    blackPolylineOptions.zIndex(5f); // Using 5 as an example, anything greater than 0 (the default) will work