Анимированный прозрачный круг в Google Maps v2 НЕ корректно анимируется

Мне удалось анимировать базовый круг на Android Google Maps v2, но я хотел сделать шаг вперед. Я хотел, чтобы анимированный круг был похож на анимированные круги Тиндера, это возможно?

Пример: http://jsfiddle.net/Y3r36/9/

Прямо сейчас я получаю беспокойную анимацию, которая очень неприемлема. Вот мой код:

public void onMapReady(GoogleMap map) {
        double latitude = 33.750587;
        double longitude = -84.4199173;

        LatLng latLng = new LatLng(latitude,longitude);

        map.moveCamera(CameraUpdateFactory.newLatLng(latLng));
        map.animateCamera(CameraUpdateFactory.zoomTo(13));
        map.addMarker(new MarkerOptions()
                .position(new LatLng(latitude, longitude))
                .title("Marker"));


        final Circle circle = mMap.addCircle(new CircleOptions()
                .center(new LatLng(latitude,longitude))
                .radius(50).fillColor(0x5500ff00).strokeWidth(0)
        );
        ValueAnimator valueAnimator = new ValueAnimator();
        valueAnimator.setRepeatCount(ValueAnimator.INFINITE);
        valueAnimator.setRepeatMode(ValueAnimator.RESTART);
        valueAnimator.setIntValues(0, 100);
        valueAnimator.setDuration(1000);
        valueAnimator.setEvaluator(new IntEvaluator());
        valueAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                float animatedFraction = valueAnimator.getAnimatedFraction();
                Log.e("", "" + animatedFraction);
                circle.setRadius(animatedFraction * 100);
            }
        });
        valueAnimator.start();

Я открыт для любых предложений. Спасибо

5 ответов

Решение

Очевидно, есть две библиотеки github, которые можно использовать для создания этого эффекта ряби на маркерах, если они используются правильно:

https://github.com/skyfishjy/android-ripple-background

https://github.com/markushi/android-circlebutton

Беспокойная анимация - известная проблема. Чтобы обойти эту проблему, вы можете использовать GroundOverlay вместо круга.

Вот пример, чтобы получить эффект, который вы упомянули:

private static final int DURATION = 3000;
private void showRipples(LatLng latLng) {
    GradientDrawable d = new GradientDrawable();
    d.setShape(GradientDrawable.OVAL);
    d.setSize(500,500);
    d.setColor(0x5500ff00);
    d.setStroke(0, Color.TRANSPARENT);

    Bitmap bitmap = Bitmap.createBitmap(d.getIntrinsicWidth()
            , d.getIntrinsicHeight()
            , Bitmap.Config.ARGB_8888);

    // Convert the drawable to bitmap
    Canvas canvas = new Canvas(bitmap);
    d.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
    d.draw(canvas);

    // Radius of the circle
    final int radius = 50;

    // Add the circle to the map
    final GroundOverlay circle = map.addGroundOverlay(new GroundOverlayOptions()
            .position(latLng, 2 * radius).image(BitmapDescriptorFactory.fromBitmap(bitmap)));

    // Prep the animator   
    PropertyValuesHolder radiusHolder = PropertyValuesHolder.ofFloat("radius", 0, radius);
    PropertyValuesHolder transparencyHolder = PropertyValuesHolder.ofFloat("transparency", 0, 1);

    ValueAnimator valueAnimator = new ValueAnimator();
    valueAnimator.setRepeatCount(ValueAnimator.INFINITE);
    valueAnimator.setRepeatMode(ValueAnimator.RESTART);
    valueAnimator.setValues(radiusHolder, transparencyHolder);
    valueAnimator.setDuration(DURATION);
    valueAnimator.setEvaluator(new FloatEvaluator());
    valueAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
    valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator valueAnimator) {
            float animatedRadius = (float) valueAnimator.getAnimatedValue("radius");
            float animatedAlpha = (float) valueAnimator.getAnimatedValue("transparency");
            circle.setDimensions(animatedRadius * 2);
            circle.setTransparency(animatedAlpha);
        }
    });

    // start the animation
    valueAnimator.start();
}

Теперь о волновом эффекте:

showRipples(latLng);
    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            showRipples(latLng);
        }
    }, DURATION - 500);

ОБНОВЛЕНИЕ: эта проблема была исправлена

В соответствии с проблемой мисс Неха

да, это можно использовать с маркером

просто следуйте как указано выше ответ и

записать код анимации в событие OnMarkerClick

лайк

 if(circle!=null)
                {
                    circle.remove();
                }


                circle = mMap.addGroundOverlay(new GroundOverlayOptions()
                        .position(marker.getPosition(), 2 * radius).image(BitmapDescriptorFactory.fromBitmap(drawcircle())));



                valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator valueAnimator) {
                        float animatedFraction = valueAnimator.getAnimatedFraction();
                        circle.setDimensions(animatedFraction * radius * 2);
                    }
                });

                valueAnimator.start();

Это простые парни

сначала вам нужно GroundOverlay объект и радиус объекта вне класса

 GroundOverlay circle;
 int radius = 100000;

затем создайте объект valueanimator и инициируйте его

 final ValueAnimator valueAnimator = new ValueAnimator();
        valueAnimator.setRepeatCount(ValueAnimator.INFINITE);
        valueAnimator.setRepeatMode(ValueAnimator.RESTART);
        valueAnimator.setIntValues(0, radius);
        valueAnimator.setDuration(3000);
        valueAnimator.setEvaluator(new IntEvaluator());
        valueAnimator.setInterpolator(new AccelerateDecelerateInterpolator());

а затем используйте следующий код, чтобы показать аниматино

circle = mMap.addGroundOverlay(new GroundOverlayOptions()
                        .position(marker.getPosition(), 2 * radius).image(BitmapDescriptorFactory.fromBitmap(drawcircle())));



                valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator valueAnimator) {
                        float animatedFraction = valueAnimator.getAnimatedFraction();
                        circle.setDimensions(animatedFraction * radius * 2);
                    }
                });

                valueAnimator.start();

Я использую эту библиотеку:

См маркер

Просто:

private void initRadar(Location location){
    mapRadar = new MapRadar(map, new LatLng(location.getLatitude(),location.getLongitude()),getContext());
    mapRadar.withDistance(2000);
    mapRadar.withClockwiseAnticlockwiseDuration(2);
    //mapRadar.withOuterCircleFillColor(Color.parseColor("#12000000"));
    mapRadar.withOuterCircleStrokeColor(ContextCompat.getColor(getContext(),R.color.primary));
    //mapRadar.withRadarColors(Color.parseColor("#00000000"), Color.parseColor("#ff000000"));  //starts from transparent to fuly black
    mapRadar.withRadarColors(ContextCompat.getColor(getContext(),R.color.blue_light), ContextCompat.getColor(getContext(),R.color.blue_dark));  //starts from transparent to fuly black
    //mapRadar.withOuterCircleStrokewidth(7);
    //mapRadar.withRadarSpeed(5);
    mapRadar.withOuterCircleTransparency(0.5f);
    mapRadar.withRadarTransparency(0.5f);
    mapRadar.startRadarAnimation();

}
Другие вопросы по тегам