百度地图SDK Android版开发 8 覆盖物示例2动画

前言

前文介绍了百度地图Marker支持多种动画类型:

  • 帧动画;
  • 加载动画(包括从天上掉下、从地下生长和跳跃动画);
  • Animation动画(包括平移、旋转、透明、缩放、单边缩放和组合动画)。

本文重点介绍Marker动画相关的类和接口,以及示例代码。

动画相关的类和接口

帧动画

帧动画的功能通过MarkerOptions类来设置,一次传入一个Icon列表,通过period设定刷新的帧间隔。

MarkerOptions

类型方法说明
MarkerOptionsicons(ArrayList< BitmapDescriptor > icons)设置 Marker 覆盖物的图标,相同图案的 icon 的 marker 最好使用同一个 BitmapDescriptor 对象以节省内存空间。
MarkerOptionsperiod(int period)设置多少帧刷新一次图片资源,Marker动画的间隔时间,值越小动画越快。
MarkerOptionsinterval(int mInterval)v7.6.0新增接口。设置marker多帧图片播放时间间隔(ms)。 地图绘制方式升级为overlay2.0时,该接口生效。

加载动画

自v3.6.0版本起,SDK提供了加载Marker时的动画效果,通过animateType设置动画类型。

MarkerOptions

类型方法说明
MarkerOptionsanimateType(MarkerOptions.MarkerAnimateType type)设置marker动画类型,见 MarkerAnimateType(从天上掉下,从地下生长,跳跃),默认无动画

MarkerOptions.MarkerAnimateType 动画类型

位置说明
MarkerOptions.MarkerAnimateType.none没效果
MarkerOptions.MarkerAnimateType.drop从天上掉下
MarkerOptions.MarkerAnimateType.grow从地面生长
MarkerOptions.MarkerAnimateType.jump跳动

Animation动画

Marker还支持设置旋转、缩放、平移、透明和组合动画效果。通过Marker类setAnimation方法设置。

Marker

类型方法说明
voidsetAnimation(Animation animation)设置 Marker 覆盖物的动画
voidsetAnimation(Animation animation, TypeEvaluator typeEvaluator)设置 Marker 覆盖物的动画与估值器
voidstartAnimation()开启 Marker 覆盖物的动画
voidcancelAnimation()取消 Marker 覆盖物的动画

Animation类及其子类

动画类别说明
抽象类AnimationMarker 动画接口类
平移动画TransformationMarker 平移动画接口类
旋转动画RotateAnimationMarker 旋转动画接口类
透明度动画AlphaAnimationMarker 透明动画接口类
缩放动画ScaleAnimationMarker 缩放动画接口类
单边缩放动画(X或Y方向)SingleScaleAnimationMarker X或Y方向单独缩放动画类
组合动画AnimationSetMarker 动画集合接口类
Transformation
+Transformation(LatLng... values)
+void setRepeatCount(repeatCount)
+void setRepeatMode(repeatMode)
Animation
+long getDuration()
+int getRepeatCount()
+Animation.RepeatMode getRepeatMode()
+abstract void setDuration(duration)
+abstract void setAnimationListener(animationListener)
+abstract void setInterpolator(interpolator)
+abstract void cancel()
RotateAnimation
+RotateAnimation(fromDegrees, toDegrees)
+void setRepeatCount(repeatCount)
+void setRepeatMode(repeatMode)
AlphaAnimation
+AlphaAnimation(float... alpha)
+void setRepeatCount(repeatCount)
+void setRepeatMode(repeatMode)
ScaleAnimation
+ScaleAnimation(float... scale)
+void setRepeatCount(repeatCount)
+void setRepeatMode(repeatMode)
SingleScaleAnimation
+SingleScaleAnimation(scaleType, float... scale)
+void setRepeatCount(repeatCount)
+void setRepeatMode(repeatMode)
AnimationSet
+AnimationSet()
+void addAnimation(animation)
+void setAnimatorSetMode(combinationMode)
Animation
类型方法说明
longgetDuration()获取设置动画持续时间
intgetRepeatCount()获取动画重复执行的次数。默认为0
Animation.RepeatModegetRepeatMode()重复模式
abstract voidsetAnimationListener(Animation.AnimationListener animationListener)设置 Marker 动画监听
abstract voidsetDuration(long duration)设置 Marker 动画执行时间
abstract voidsetInterpolator(Interpolator interpolator)设置 Marker 动画插值器
abstract voidcancel()取消 Marker 动画
  • Animation.RepeatMode 重复执行模式
枚举常量说明
Animation.RepeatMode.RESTART动画结束后从头播放,最大重复次数受RepeatCount限制
Animation.RepeatMode.REVERSE动画结束后从尾倒放,最大重复次数受RepeatCount限制
  • AnimationListener 动画侦听
// 动画侦听
public interface AnimationListener {
    // 动画开始回调
    void onAnimationStart();

    // 动画结束回调
    void onAnimationEnd();

    // 动画取消回调
    void onAnimationCancel();

    // 动画重复回调
    void onAnimationRepeat();
}
Transformation
说明说明
Transformation(LatLng… values)构造
Transformation(Point… values)构造
voidsetRepeatCount(int repeatCount)设置 Marker 动画重复次数
voidsetRepeatMode(Animation.RepeatMode repeatMode)设置 Marker 动画重复模式
RotateAnimation
说明说明
RotateAnimation(float fromDegrees, float toDegrees)构造
floatgetFromDegrees()
floatgetToDegrees()
voidsetRepeatCount(int repeatCount)设置 Marker 动画重复次数
voidsetRepeatMode(Animation.RepeatMode repeatMode)设置 Marker 动画重复模式
AlphaAnimation
说明说明
AlphaAnimation(float… alpha)
float[]getAlpha()
voidsetRepeatCount(int repeatCount)设置 Marker 动画重复次数
voidsetRepeatMode(Animation.RepeatMode repeatMode)设置 Marker 动画重复模式
ScaleAnimation
说明说明
ScaleAnimation(float… scale)
float[]getScale()
voidsetRepeatCount(int repeatCount)设置 Marker 动画重复次数
voidsetRepeatMode(Animation.RepeatMode repeatMode)设置 Marker 动画重复模式
SingleScaleAnimation
说明说明
SingleScaleAnimation(SingleScaleAnimation.ScaleType scaleType, float… scale)
float[]getScale()
SingleScaleAnimation.ScaleTypegetScaleType()
voidsetRepeatCount(int repeatCount)设置 Marker 动画重复次数
voidsetRepeatMode(Animation.RepeatMode repeatMode)设置 Marker 动画重复模式
  • SingleScaleAnimation.ScaleType 单边缩放类型
枚举常量说明
SingleScaleAnimation.ScaleType.SCALE_XMarker X方向单独缩放动画
SingleScaleAnimation.ScaleType.SCALE_YMarker Y方向单独缩放动画
AnimationSet
说明说明
AnimationSet()构造
voidaddAnimation(Animation animation)向 Marker 动画集合中添加动画
voidsetAnimatorSetMode(int combinationMode)设置 Marker 集合动画播放模式 0:组合播放 1:顺序播放

Marker动画示例

界面布局

在这里插入图片描述

  • 布局文件
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MapMarkerAnimationActivity">

    <com.baidu.mapapi.map.MapView
        android:id="@+id/bmapView"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:clickable="true"
        app:layout_constraintBottom_toTopOf="@id/bottomView"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.appcompat.widget.LinearLayoutCompat
        android:id="@+id/bottomView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toBottomOf="@id/bmapView">

        <RadioGroup
            android:id="@+id/RadioGroup"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@android:color/background_dark"
            android:gravity="center_horizontal"
            android:orientation="horizontal"
            android:paddingHorizontal="10dp">

            <RadioButton
                android:id="@+id/frameAnimation"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:checked="true"
                android:onClick="setAnimationFlag"
                android:text="帧动画"
                android:textColor="@color/white"
                android:textStyle="bold" />

            <RadioButton
                android:id="@+id/loadAnimation"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:onClick="setAnimationFlag"
                android:text="加载动画"
                android:textColor="@color/white"
                android:textStyle="bold" />

            <RadioButton
                android:id="@+id/animation"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:onClick="setAnimationFlag"
                android:text="Animation动画"
                android:textColor="@color/white"
                android:textStyle="bold" />

        </RadioGroup>

    </androidx.appcompat.widget.LinearLayoutCompat>
</androidx.constraintlayout.widget.ConstraintLayout>

MapMarkAnimate类

  • 以下是MapMarkAnimate部分代码。

常量

public final static String FRAME_ANIMATION = "Frame"; // 帧动画

public final static String DROP_ANIMATION = "Drop"; // 加载动画 从天上掉下
public final static String GROW_ANIMATION = "Grow"; // 加载动画 从地下生长
public final static String JUMP_ANIMATION = "Jump"; // 加载动画 跳跃

public final static String TRANSFORMATION_ANIMATION = "Transformation"; // 平移动画
public final static String ROTATE_ANIMATION = "Rotate"; // 旋转动画
public final static String ALPHA_ANIMATION = "Alpha"; // 透明度动画
public final static String SCALE_ANIMATION = "Scale"; // 缩放动画
public final static String SINGLE_SCALE_ANIMATION = "SingleScale"; // 单边缩放动画 X或Y方向
public final static String ANIMATION_SET = "AnimationSet"; // 组合动画

成员变量

// 覆盖物列表
List<Overlay> overlays = new ArrayList<>();
// 选中的状态
List<String> selectedFlags = new ArrayList<>();
// 坐标点集
List<LatLng> points = new ArrayList<>();

ArrayList<BitmapDescriptor> bitmaps = new ArrayList<>();

初始值

selectedFlags.add(FRAME_ANIMATION);
selectedFlags.add(FRAME_ANIMATION);
selectedFlags.add(FRAME_ANIMATION);

points.add(new LatLng(39.97923, 116.357428));
points.add(new LatLng(39.94923, 116.397428));
points.add(new LatLng(39.97923, 116.437428));
points.add(new LatLng(39.92353, 116.490705));
points.add(new LatLng(40.023537, 116.289429));
points.add(new LatLng(40.022211, 116.406137));

// 相同图案的 icon 的 marker 最好使用同一个 BitmapDescriptor 对象以节省内存空间。
int[] drawableIds = BubbleIcons.Number;
for (int drawableId : drawableIds) {
    BitmapDescriptor bitmap = BitmapDescriptorFactory.fromResource(drawableId);
    bitmaps.add(bitmap);
}

创建覆盖物

public void addMarkers() {
    if (selectedFlags.isEmpty())
        return;

    int markerSize = selectedFlags.size();
    for (int i = 0; i < markerSize; ++i) {
        LatLng point = points.get(i);
        String flag = selectedFlags.get(i);
        switch (flag) {
        case FRAME_ANIMATION:
            addFrameAnimation(point, bitmaps);
            break;
        case DROP_ANIMATION:
        case GROW_ANIMATION:
        case JUMP_ANIMATION:
            addLoadAnimation(point, bitmaps.get(i), flag);
            break;
        default:
            addAnimation(point, bitmaps.get(i), flag);
            break;
        }
    }
}
创建Marker(帧动画)
MarkerOptions option = new MarkerOptions()
        .position(point)
        .icons(bitmaps) // 设置覆盖物的图标
        .period(10); // 设置多少帧刷新一次图片资源,值越小动画越快 默认为20,最小为1

Marker marker = (Marker) map.addOverlay(option);
overlays.add(marker);
创建Marker(加载动画)
private void addLoadAnimation(LatLng point, BitmapDescriptor bitmap, String flag) {
    MarkerOptions.MarkerAnimateType type = MarkerOptions.MarkerAnimateType.none;
    switch (flag) {
    case DROP_ANIMATION:
        type = MarkerOptions.MarkerAnimateType.drop;
        break;
    case GROW_ANIMATION:
        type = MarkerOptions.MarkerAnimateType.grow;
        break;
    case JUMP_ANIMATION:
        type = MarkerOptions.MarkerAnimateType.jump;
        break;
    }

    if (type == MarkerOptions.MarkerAnimateType.none)
        return;

    MarkerOptions option = new MarkerOptions()
            .position(point) // 设置覆盖物的位置坐标
            .icon(bitmap) // 设置覆盖物的图标,
            .animateType(type); // 设置动画类型

    Marker marker = (Marker) map.addOverlay(option);
    overlays.add(marker);
}
创建Marker(Animation动画)
private void addAnimation(LatLng point, BitmapDescriptor bitmap, String flag) {
    Animation animation = null;
    switch (flag) {
    case TRANSFORMATION_ANIMATION:
        animation = getTransformation(point);
        break;
    case ROTATE_ANIMATION:
        animation = getRotateAnimation();
        break;
    case ALPHA_ANIMATION:
        animation = getAlphaAnimation();
        break;
    case SCALE_ANIMATION:
        animation = getScaleAnimation();
        break;
    case SINGLE_SCALE_ANIMATION:
        animation = getSingleScaleAnimation();
        break;
    case ANIMATION_SET:
        animation = getAnimationSet();
        break;
    }

    if (animation == null)
        return;

    MarkerOptions option = new MarkerOptions()
            .position(point)
            .icon(bitmap);

    Marker marker = (Marker) map.addOverlay(option);
    overlays.add(marker);
    marker.setAnimation(animation);
    marker.startAnimation();
}
创建Animation
  • 创建平移动画、旋转动画、透明度动画、缩放动画、单边缩放动画、创建组合动画。
// 创建平移动画
Animation getTransformation(LatLng point) {
    Point pt1 = map.getProjection().toScreenLocation(point);
    Point pt2 = new Point(pt1.x, pt1.y - 100);
    LatLng toPoint = map.getProjection().fromScreenLocation(pt2);

    Transformation animation = new Transformation(point, toPoint, point);

    // 设置动画执行时间
    animation.setDuration(500);
    // 设置动画重复模式
    animation.setRepeatMode(Animation.RepeatMode.RESTART);
    // 设置动画重复次数
    animation.setRepeatCount(1);

    animation.setAnimationListener(new Animation.AnimationListener() {
        @Override
        public void onAnimationStart() {
        }

        @Override
        public void onAnimationEnd() {
        }

        @Override
        public void onAnimationCancel() {
        }

        @Override
        public void onAnimationRepeat() {

        }
    });

    return animation;
}

// 创建旋转动画
Animation getRotateAnimation() {
    RotateAnimation animation = new RotateAnimation(0f, 360f);

    // 设置动画执行时间
    animation.setDuration(1000);
    // 设置动画重复模式
    animation.setRepeatMode(Animation.RepeatMode.RESTART);
    // 设置动画重复次数
    animation.setRepeatCount(1);

    setAnimationListener(animation);

    return animation;
}

// 创建透明度动画
Animation getAlphaAnimation() {
    AlphaAnimation animation = new AlphaAnimation(1f, 0f, 1f);

    // 设置动画执行时间
    animation.setDuration(3000);
    // 设置动画重复模式
    animation.setRepeatMode(Animation.RepeatMode.RESTART);
    // 设置动画重复次数
    animation.setRepeatCount(1);

    setAnimationListener(animation);

    return animation;
}

// 创建缩放动画
Animation getScaleAnimation() {
    float scale1 = 1.0f;
    float scale2 = 2.0f;
    ScaleAnimation animation = new ScaleAnimation(scale1, scale2, scale1);

    // 设置动画执行时间
    animation.setDuration(2000);
    // 设置动画重复模式
    animation.setRepeatMode(Animation.RepeatMode.RESTART);
    // 设置动画重复次数
    animation.setRepeatCount(1);

    setAnimationListener(animation);
    return animation;
}

// 创建单边缩放动画
Animation getSingleScaleAnimation() {
    SingleScaleAnimation.ScaleType scaleType = SingleScaleAnimation.ScaleType.SCALE_X;
    float scale1 = 1.0f;
    float scale2 = 2.0f;
    SingleScaleAnimation animation = new SingleScaleAnimation(scaleType,
            scale1, scale2, scale1);

    // 设置动画执行时间
    animation.setDuration(1000);
    // 设置动画重复模式
    animation.setRepeatMode(Animation.RepeatMode.RESTART);
    // 设置动画重复次数
    animation.setRepeatCount(1);

    setAnimationListener(animation);
    return animation;
}

// 创建组合动画
Animation getAnimationSet() {
    // 动画集合接口类
    AnimationSet animation = new AnimationSet();

    // 向动画集合中添加动画
    animation.addAnimation(getAlphaAnimation());
    animation.addAnimation(getRotateAnimation());
    animation.addAnimation(getSingleScaleAnimation());
    animation.addAnimation(getScaleAnimation());

    // 设置集合动画播放模式 0:组合播放 1:顺序播放
    animation.setAnimatorSetMode(0);
    // 设置动画插值器
    animation.setInterpolator(new LinearInterpolator());

    setAnimationListener(animation);
    return animation;
}

移除覆盖物

public void removeOverlay() {
    //map.removeOverLays(overlays);
    for (Overlay overlay : overlays) {
        if (overlay instanceof Marker) {
            ((Marker) overlay).cancelAnimation();
        }
        overlay.remove();
    }
    overlays.clear();
}

设置属性

public void setFlags(List<String> flags) {
    selectedFlags.clear();
    selectedFlags.addAll(flags);

    removeOverlay();
    addMarkers();
}

加载地图和释放地图

public void onMapLoaded() {
    addMarkers();
}

public void onMapDestroy() {
    removeOverlay();

    for (BitmapDescriptor bitmap : bitmaps) {
        bitmap.recycle();
    }
    bitmaps = null;
}

MapMarkerAnimationActivity类

  • 以下是MapMarkerAnimationActivity类部分代码

控件响应事件

public void setAnimationFlag(View view) {
    boolean checked = ((RadioButton) view).isChecked();
    int id = view.getId();
    if (!checked)
        return;

    List<String> flags;
    if (id == R.id.frameAnimation) {
        flags = Arrays.asList(
                MapMarkerAnimation.FRAME_ANIMATION,
                MapMarkerAnimation.FRAME_ANIMATION,
                MapMarkerAnimation.FRAME_ANIMATION);
    } else if (id == R.id.loadAnimation) {
        flags = Arrays.asList(
                MapMarkerAnimation.DROP_ANIMATION,
                MapMarkerAnimation.GROW_ANIMATION,
                MapMarkerAnimation.JUMP_ANIMATION);
    } else if (id == R.id.animation) {
        flags = Arrays.asList(
                MapMarkerAnimation.TRANSFORMATION_ANIMATION,
                MapMarkerAnimation.ROTATE_ANIMATION,
                MapMarkerAnimation.ALPHA_ANIMATION,
                MapMarkerAnimation.SCALE_ANIMATION,
                MapMarkerAnimation.SINGLE_SCALE_ANIMATION,
                MapMarkerAnimation.ANIMATION_SET);
    } else {
        return;
    }
    mapMarkerAnimation.setFlags(flags);
}

运行效果图

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值