如何在markerOptions中制作动画图标? [GoogleMaps API]

4

有没有一种方法可以对图标进行动画处理?我需要在我的Google地图上的自定义可绘制标记上应用“波浪”动画。欢迎任何建议!

注意:我的计划现在是运行一个处理程序工作线程,不断调用“setIcon”方法以动画化图标。

期望效果:

enter image description here

我的图标可绘制对象:

enter image description here

XML:

<shape
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">
    <solid
        android:color="#0093e8"/>
    <size
        android:width="120dp"
        android:height="120dp"/>
</shape>

这是我的onMapReady方法:

@Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;

        mDotMarkerBitmap = generateBitmapFromDrawable();
        markerOptions = new MarkerOptions()
                .position(xDesign)
                .title("xDesign in Edinburgh")
                .icon(BitmapDescriptorFactory.fromBitmap(mDotMarkerBitmap));
        mXDesignMarker = mMap.addMarker(markerOptions);


        BitmapDescriptor bitmapDescriptor = markerOptions.getIcon();


        Animation fadeOut = new AlphaAnimation(1, 0);
        fadeOut.setDuration(1000);
        AnimationSet animation = new AnimationSet(true);
        animation.addAnimation(fadeOut);

        //   Icons dont have animate method     icon.setAnimation(animation);

        mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(xDesign, 15));
    }

我的generateBitmapFromDrawable方法:

private Bitmap generateBitmapFromDrawable() {
    int px = getResources().getDimensionPixelSize(R.dimen.map_dot_marker_size);
    Bitmap mDotMarkerBitmap = Bitmap.createBitmap(px, px, Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(mDotMarkerBitmap);
    Drawable shape = getResources().getDrawable(R.drawable.circle_drawable);
    shape.setBounds(0, 0, mDotMarkerBitmap.getWidth(), mDotMarkerBitmap.getHeight());
    shape.draw(canvas);
    return mDotMarkerBitmap;
}

这被称为涟漪效应,有一些自定义库可用。https://dev59.com/c18d5IYBdhLWcg3woDYZ - Antonios Tsimourtos
2个回答

3

我使用了自定义动画类来实现这个功能:

public class RadiusAnimation extends Animation {
    private GroundOverlay groundOverlay;
    private final int startingSize = 100;

    public RadiusAnimation(GroundOverlay groundOverlay) {
        this.groundOverlay = groundOverlay;

    }

    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        groundOverlay.setDimensions((startingSize * interpolatedTime));
        groundOverlay.setTransparency(interpolatedTime);

    }


    @Override
    public void initialize(int width, int height, int parentWidth, int parentHeight) {
        super.initialize(width, height, parentWidth, parentHeight);
    }
}

然后在我的mapFragment中:

public class MapFragment extends Fragment implements OnMapReadyCallback {

    private RadiusAnimation groundAnimation;
    private AnimationSet breadingAnimations;

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        rippleBackground = new RippleBackground(getActivity());
        rippleBackground.setBackgroundColor(ContextCompat.getColor(getActivity(),
                R.color.pulseMarker1));

        mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);

        breadingAnimations = new AnimationSet(false);
    }

@Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;
//Add smallest image drawable overlay

        Bitmap mDotMarkerBitmap1 = generateBitmapFromDrawable(R.drawable.circle_drawable);

        final int widthOne = 80;
        final int animationDurationOne = 1200;

        GroundOverlay groundOverlay1 = mMap.addGroundOverlay(new GroundOverlayOptions()
                .image(BitmapDescriptorFactory.fromBitmap(mDotMarkerBitmap1))
                .position(xDesign, widthOne));

        groundAnimation = new RadiusAnimation(groundOverlay1);
        groundAnimation.setRepeatCount(Animation.INFINITE);
        groundAnimation.setRepeatMode(Animation.RESTART);

        groundAnimation.setDuration(animationDurationOne);
//        groundAnimation.setStartOffset(700);
        breadingAnimations.addAnimation(groundAnimation);


        Bitmap mDotMarkerBitmap2 = generateBitmapFromDrawable(R.drawable.circle_drawable2);
        final int widthTwo = 200;
        final int animationDurationTwo = 2000;
        GroundOverlay groundOverlay2 = mMap.addGroundOverlay(new GroundOverlayOptions()
                .image(BitmapDescriptorFactory.fromBitmap(mDotMarkerBitmap2))
                .position(xDesign, widthTwo));

        Animation groundAnimation2 = new RadiusAnimation(groundOverlay2);
        groundAnimation2.setRepeatCount(Animation.INFINITE);
        groundAnimation2.setRepeatMode(Animation.RESTART);
        groundAnimation2.setDuration(animationDurationTwo);
//        groundAnimation2.setStartOffset(1500);
        breadingAnimations.addAnimation(groundAnimation2);


        Bitmap mDotMarkerBitmap3 = generateBitmapFromDrawable(R.drawable.circle_drawable3);
        final int widthThree = 300;
        final int animationDurationThree = 3000;
        GroundOverlay groundOverlay3 = mMap.addGroundOverlay(new GroundOverlayOptions()
                .image(BitmapDescriptorFactory.fromBitmap(mDotMarkerBitmap3))
                .position(xDesign, widthThree));

        Animation groundAnimation3 = new RadiusAnimation(groundOverlay3);
        groundAnimation3.setRepeatCount(Animation.INFINITE);
        groundAnimation3.setRepeatMode(Animation.RESTART);
//        groundAnimation3.setStartOffset(500);
        groundAnimation3.setDuration(animationDurationThree);

        breadingAnimations.addAnimation(groundAnimation3);

        mapFragment.getView().startAnimation(breadingAnimations); // start animation


        mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(xDesign, zoomLeval));
    }

    private void logThis(String message) {
        Log.d(TAG, message);
    }

    @NonNull
    private Bitmap generateBitmapFromDrawable(int drawablesRes) {
        int px = getResources().getDimensionPixelSize(R.dimen.map_dot_marker_size);
        Bitmap mDotMarkerBitmap = Bitmap.createBitmap(px, px, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(mDotMarkerBitmap);
        Drawable shape = getResources().getDrawable(drawablesRes);
        shape.setBounds(0, 0, mDotMarkerBitmap.getWidth(), mDotMarkerBitmap.getHeight());
        shape.draw(canvas);
        return mDotMarkerBitmap;
    }


}

RippleBackground?你没有在这里描述这个类!! - Abhijeet

-2

你可以在XML中创建你想要的波浪动画

circle_drawable.xml

 <animation-list android:id="@+id/selected" android:oneshot="false">
    <item android:drawable="@drawable/image1" android:duration="50" />
    <item android:drawable="@drawable/image2" android:duration="50" />
    <item android:drawable="@drawable/image3" android:duration="50" />//you can add more xmls and alter the duration to make the animation look good
 </animation-list>

image1.xml

<shape
   xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
   <solid
    android:color="@color/dark_blue"/>
   <size
    android:width="60dp"
    android:height="60dp"/>
</shape>

image2.xml

<shape
   xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">
   <solid
    android:color="@color/blue"/>
   <size
    android:width="90dp"
    android:height="90dp"/>
</shape>

image3.xml

<shape
     xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">
    <solid
       android:color="@color/blue"/>
    <size
    android:width="120dp"
    android:height="120dp"/>
</shape>

最后,在您的代码中添加可绘制标记。
private Bitmap generateBitmapFromDrawable() {
    int px = getResources().getDimensionPixelSize(R.dimen.map_dot_marker_size);
    Bitmap mDotMarkerBitmap = Bitmap.createBitmap(px, px, Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(mDotMarkerBitmap);
    Drawable shape = getResources().getDrawable(R.drawable.circle_drawable);
    shape.setBounds(0, 0, mDotMarkerBitmap.getWidth(), mDotMarkerBitmap.getHeight());
    shape.draw(canvas);

     // Get the background, which has been compiled to an AnimationDrawable object.
//Edited:
         AnimationDrawable frameAnimation = (AnimationDrawable) view.getBackground(); //view is the marker

 // Start the animation (looped playback by default).

 frameAnimation.start();

    return mDotMarkerBitmap;
}

参考 https://developer.android.com/reference/android/graphics/drawable/AnimationDrawable.html


谢谢您的建议。我确实尝试了,但不幸的是,我无法看到任何动画播放。它只是一个静态的蓝色实心圆:/ - Georgi Koemdzhiev
谢谢,但是Marker类没有getBackground()方法或任何类似的方法,所以我无法应用你的建议 :/ - Georgi Koemdzhiev
@Saravnfern,不是完全符合我的要求,但因为这是唯一的答案,所以我接受了它。再次感谢您的帮助! :) - Georgi Koemdzhiev
view.getBackground(); //view是标记...当然 - Pablo Cegarra
marker.getBackground(); 它没有背景。 - Syed Arsalan Shah

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接