标签: 动画 示例 float ANIMATION animation new Android Animation 高德
高德地图SDK Android版开发 8 覆盖物示例2动画
前言
前文介绍了高德地图Marker
支持多种动画类型:
帧动画; Animation
动画(包括平移、旋转、透明、缩放和组合动画)。
本文重点介绍Marker
动画相关的类和接口,以及示例代码。
动画相关的类和接口
帧动画
帧动画 的功能通过MarkerOptions
类来设置,一次传入一个Icon列表,通过period
设定刷新的帧间隔。
MarkerOptions
类型 方法 说明 MarkerOptions icons
(ArrayList< BitmapDescriptor > icons)设置Marker覆盖物的动画帧图标列表,多张图片模拟gif的效果。 MarkerOptions period
(int period)设置多少帧刷新一次图片资源,Marker动画的间隔时间,值越小动画越快。
Animation动画
Marker还支持设置旋转、缩放、平移、透明和组合动画效果 。通过Marker类setAnimation方法设置。
类 说明 说明 void setAnimation
(Animation animation)设置动画。动画包含,旋转,缩放,消失,平移以及它们的组合动画 boolean startAnimation
()开始动画
Animation类及其子类
动画类别 类 说明 抽象类 Animation
动画,可用于支持动画的覆盖物。使用方法如同Android系统自带的Animation 移动动画 TranslateAnimation
控制移动的动画类 旋转动画 RotateAnimation
控制旋转的动画类 透明度动画 AlphaAnimation
控制透明度的动画类 缩放动画 ScaleAnimation
控制缩放的动画类 组合动画 AnimationSet
动画集合
TranslateAnimation
+TranslateAnimation(latLng)
#String getAnimationType()
Animation
+int getFillMode()
+int getRepeatCount()
+int getRepeatMode()
+void setAnimationListener(listener)
+void setDuration(duration)
+void setFillMode(fillMode)
+void setInterpolator(interpolator)
+void setRepeatCount(repeatCount)
+void setRepeatMode(repeatMode)
RotateAnimation
+RotateAnimation(fromdegree, todegree)
#String getAnimationType()
AlphaAnimation
+AlphaAnimation(fromAlpha, toAlpha)
#String getAnimationType()
ScaleAnimation
+ScaleAnimation(fromX, toX, fromY, toY)
#String getAnimationType()
AnimationSet
+AnimationSet(shareInterpolator)
+void addAnimation(animation)
+void cleanAnimation()
#String getAnimationType()
Animation
类 说明 说明 int getFillMode
()获取动画执行完成后的状态 int getRepeatCount
()获取动画重复执行的次数 int getRepeatMode
()重复执行的模式 void setAnimationListener
(Animation.AnimationListener listener)设置动画监听器 void setDuration
(long duration)设置动画持续时间。如果设置为负数,会修正为0 void setFillMode
(int fillMode)设置动画执行完成后的状态。默认FILL_MODE_FORWARDS
void setInterpolator
(Interpolator interpolator)设置插值器。默认是线性插值器 void setRepeatCount
(int repeatCount)设置动画重复执行的次数。默认为0 void setRepeatMode
(int repeatMode)重复执行的模式。默认RESTART
类型 常量 说明 static int FILL_MODE_BACKWARDS
动画执行后保持在第一帧 static int FILL_MODE_FORWARDS
动画执行后保持在最后一帧 static int INFINITE
无限期地重复动画 static int RESTART
动画结束后从头播放,最大重复次数受Animation.setRepeatCount(int) 限制 static int REVERSE
动画结束后从尾倒放,最大重复次数受Animation.setRepeatCount(int) 限制
// 设置重复执行的模式
animation.setRepeatMode(Animation.RESTART);
// 设置动画执行后保持在第一帧
animation.setFillMode(Animation.FILL_MODE_BACKWARDS);
// 设置无限期地重复动画
animation.setRepeatCount(Animation.INFINITE);
// 动画监听,包含动画开始和结束时的回调
public interface AnimationListener {
// 动画开始回调
void onAnimationStart();
// 动画结束回调
void onAnimationEnd();
}
TranslateAnimation
类 说明 说明 TranslateAnimation
(LatLng target)控制移动的动画类 protected String getAnimationType
()
RotateAnimation
类 说明 说明 RotateAnimation
(float fromdegree, float todegree)控制旋转的动画类 protected String getAnimationType
()
AlphaAnimation
类 说明 说明 AlphaAnimation
(float fromAlpha, float toAlpha)控制透明度的动画类。 透明度范围[0,1], 1为不透明 protected String getAnimationType
()
ScaleAnimation
类 说明 说明 ScaleAnimation
(float fromX, float toX, float fromY, float toY)控制缩放的动画类。 比如要实现一个Marker生长动画,可以使用 (0,1,0,1) protected String getAnimationType
()
AnimationSet
类 说明 说明 AnimationSet
(boolean shareInterpolator)动画集合 void addAnimation
(Animation animation)添加动画 void cleanAnimation
()清除动画 protected String getAnimationType
()
Marker动画示例
本示例包括帧动画、Animation动画,以及官方Demo中的生长、跳跃和呼吸动画。
界面布局
<?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.amap.api.maps.MapView
android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="0dp"
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/map">
<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/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" />
<RadioButton
android:id="@+id/demoAnimation"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="setAnimationFlag"
android:text="Demo动画"
android:textColor="@color/white"
android:textStyle="bold" />
</RadioGroup>
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.constraintlayout.widget.ConstraintLayout>
MapMarkAnimate类
常量
public final static String FRAME_ANIMATION = "Frame"; // 帧动画
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"; // 组合动画
public final static String DEMO_GROW_ANIMATION = "Grow"; // Demo1 从地下生长
public final static String DEMO_JUMP_ANIMATION = "Jump"; // Demo2 跳跃
public final static String DEMO_BREATHE_ANIMATION = "Breathe"; // Demo3 呼吸
成员变量
// 覆盖物列表
List<BaseOverlay> overlays = new ArrayList<>();
// 选中的状态
List<String> selectedFlags = new ArrayList<>();
// 坐标点集
List<LatLng> points = new ArrayList<>();
ArrayList<BitmapDescriptor> bitmaps = new ArrayList<>();
BitmapDescriptor circleBitmap;
初始值
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));
int[] drawableIds = BubbleIcons.Number;
for (int drawableId : drawableIds) {
BitmapDescriptor bitmap = BitmapDescriptorFactory.fromResource(drawableId);
bitmaps.add(bitmap);
}
circleBitmap = BitmapDescriptorFactory.fromResource(R.drawable.marker_circle_64);
创建覆盖物
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 DEMO_GROW_ANIMATION:
case DEMO_JUMP_ANIMATION:
addSampleAnimation(point, bitmaps.get(i), flag);
break;
case DEMO_BREATHE_ANIMATION:
addBreatheAnimation(point);
break;
default:
addAnimation(point, bitmaps.get(i), flag);
break;
}
}
}
创建Marker(帧动画)
private void addFrameAnimation(LatLng point, ArrayList<BitmapDescriptor> bitmaps) {
MarkerOptions option = new MarkerOptions()
.position(point) // 当前MarkerOptions对象的经纬度
.icons(bitmaps) // Marker的动画帧列表
.period(10); // 帧数, 刷新周期,值越小速度越快。默认为20,最小为1
Marker marker = map.addMarker(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 = map.addMarker(option);
overlays.add(marker);
marker.setAnimation(animation);
marker.startAnimation();
}
创建Marker(Demo动画)
private void addSampleAnimation(LatLng point, BitmapDescriptor bitmap, String flag) {
Animation animation = null;
switch (flag) {
case DEMO_GROW_ANIMATION:
animation = getGrowAnimation();
break;
case DEMO_JUMP_ANIMATION:
animation = getJumpAnimation(point);
break;
}
if (animation == null)
return;
MarkerOptions option = new MarkerOptions()
.position(point)
.icon(bitmap);
Marker marker = map.addMarker(option);
overlays.add(marker);
marker.setAnimation(animation);
marker.startAnimation();
}
private void addBreatheAnimation(LatLng point) {
// breathe marker
MarkerOptions option = new MarkerOptions()
.position(point)
.icon(circleBitmap)
.anchor(0.5f, 0.5f)
.zIndex(1);
Marker breatheMarker = map.addMarker(option);
overlays.add(breatheMarker);
// center marker
MarkerOptions centerOption = new MarkerOptions()
.position(point)
.icon(circleBitmap)
.anchor(0.5f, 0.5f)
.zIndex(2);
Marker centerMarker = map.addMarker(centerOption);
overlays.add(centerMarker);
// 动画
Animation animation = AnimationFactory.getBreatheAnimation();
breatheMarker.setAnimation(animation);
breatheMarker.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);
TranslateAnimation animation = new TranslateAnimation(toPoint);
// 设置动画持续时间
animation.setDuration(500);
// 设置重复执行的模式
animation.setRepeatMode(Animation.RESTART);
// 设置动画重复执行的次数
animation.setRepeatCount(1);
// 动画执行后保持在第一帧
animation.setFillMode(Animation.FILL_MODE_BACKWARDS);
animation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart() {
// 动画开始回调
}
@Override
public void onAnimationEnd() {
// 动画结束回调
}
});
return animation;
}
// 创建旋转动画
Animation getRotateAnimation() {
RotateAnimation animation = new RotateAnimation(0f, 360f);
// 设置动画持续时间
animation.setDuration(1000);
// 设置重复执行的模式
animation.setRepeatMode(Animation.RESTART);
// 设置动画重复执行的次数
animation.setRepeatCount(1);
// 动画执行后保持在第一帧
animation.setFillMode(Animation.FILL_MODE_BACKWARDS);
return animation;
}
// 创建透明度动画
Animation getAlphaAnimation() {
float fromAlpha = 1.0f;
float toAlpha = 0.5f;
AlphaAnimation animation = new AlphaAnimation(fromAlpha, toAlpha);
// 设置动画持续时间
animation.setDuration(3000);
// 设置重复执行的模式
animation.setRepeatMode(Animation.RESTART);
// 设置动画重复执行的次数
animation.setRepeatCount(1);
// 动画执行后保持在第一帧
animation.setFillMode(Animation.FILL_MODE_BACKWARDS);
return animation;
}
// 创建缩放动画
Animation getScaleAnimation() {
float fromX = 1.0f; // 动画开始时横坐标位置
float toX = 2.0f; // 动画结束时横坐标位置
float fromY = 1.0f; // 动画开始时纵坐标位置
float toY = 2.0f; // 动画结束时纵坐标位置
ScaleAnimation animation = new ScaleAnimation(fromX, toX, fromY, toY);
// 设置动画持续时间
animation.setDuration(2000);
// 设置重复执行的模式
animation.setRepeatMode(Animation.RESTART);
// 设置动画重复执行的次数
animation.setRepeatCount(1);
// 动画执行后保持在第一帧
animation.setFillMode(Animation.FILL_MODE_BACKWARDS);
return animation;
}
// 单边缩放动画
Animation getSingleScaleAnimation() {
float fromX = 1.0f; // 动画开始时横坐标位置
float toX = 2.0f; // 动画结束时横坐标位置
float fromY = 1.0f; // 动画开始时纵坐标位置
float toY = 1.0f; // 动画结束时纵坐标位置
ScaleAnimation animation = new ScaleAnimation(fromX, toX, fromY, toY);
// 设置动画持续时间
animation.setDuration(1000);
// 设置重复执行的模式
animation.setRepeatMode(Animation.RESTART);
// 设置动画重复执行的次数
animation.setRepeatCount(1);
// 动画执行后保持在第一帧
animation.setFillMode(Animation.FILL_MODE_BACKWARDS);
return animation;
}
// 添加组合动画
Animation getAnimationSet() {
boolean shareInterpolator = true;
AnimationSet animation = new AnimationSet(shareInterpolator);
// 添加动画
animation.addAnimation(getAlphaAnimation());
animation.addAnimation(getRotateAnimation());
animation.addAnimation(getScaleAnimation());
// 设置插值器,默认是线性插值器
animation.setInterpolator(new LinearInterpolator());
return animation;
}
// 地上生长
Animation getGrowAnimation() {
float fromX = 0.0f; // 动画开始时横坐标位置
float toX = 1.0f; // 动画结束时横坐标位置
float fromY = 0.0f; // 动画开始时纵坐标位置
float toY = 1.0f; // 动画结束时纵坐标位置
ScaleAnimation animation = new ScaleAnimation(fromX, toX, fromY, toY);
animation.setInterpolator(new LinearInterpolator());
animation.setDuration(1000);
return animation;
}
// 跳跃动画
Animation getJumpAnimation(LatLng point) {
// 根据屏幕距离计算需要移动的目标点
Point pt1 = map.getProjection().toScreenLocation(point);
Point pt2 = new Point(pt1.x, pt1.y - 100);
LatLng toPoint = map.getProjection().fromScreenLocation(pt2);
// 使用TranslateAnimation,填写一个需要移动的目标点
Animation animation = new TranslateAnimation(toPoint);
animation.setInterpolator(new Interpolator() {
@Override
public float getInterpolation(float input) {
// 模拟重加速度的interpolator
if (input <= 0.5) {
return (float) (0.5f - 2 * (0.5 - input) * (0.5 - input));
} else {
return (float) (0.5f - Math.sqrt((input - 0.5f) * (1.5f - input)));
}
}
});
animation.setDuration(600);
return animation;
}
// 呼吸动画
Animation getBreatheAnimation() {
// 动画执行完成后,默认会保持到最后一帧的状态
boolean shareInterpolator = true;
AnimationSet animationSet = new AnimationSet(shareInterpolator);
// 1. 透明度动画
float fromAlpha = 0.5f;
float toAlpha = 0f;
AlphaAnimation alphaAnimation = new AlphaAnimation(fromAlpha, toAlpha);
alphaAnimation.setDuration(2000);
// 设置不断重复
alphaAnimation.setRepeatCount(Animation.INFINITE);
// 2. 缩放动画
float fromX = 1.0f; // 动画开始时横坐标位置
float toX = 3.5f; // 动画结束时横坐标位置
float fromY = 1.0f; // 动画开始时纵坐标位置
float toY = 3.5f; // 动画结束时纵坐标位置
ScaleAnimation scaleAnimation = new ScaleAnimation(fromX, toX, fromY, toY);
scaleAnimation.setDuration(2000);
// 设置不断重复
scaleAnimation.setRepeatCount(Animation.INFINITE);
// 添加动画
animationSet.addAnimation(alphaAnimation);
animationSet.addAnimation(scaleAnimation);
// 设置插值器,默认是线性插值器
animationSet.setInterpolator(new LinearInterpolator());
return animationSet;
}
移除覆盖物
public void removeOverlay() {
// 从地图上删除所有的覆盖物(marker,circle,polyline 等对象),
// 但myLocationOverlay(内置定位覆盖物)除外。
// boolean isKeepMyLocationOverlay = true;
// map.clear(isKeepMyLocationOverlay);
for (BaseOverlay overlay : overlays) {
if (overlay instanceof Marker) {
Marker marker = (Marker) overlay;
marker.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;
if (circleBitmap != null)
circleBitmap.recycle();
circleBitmap = 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.animation) {
flags = Arrays.asList(
MapMarkerAnimation.TRANSFORMATION_ANIMATION,
MapMarkerAnimation.ROTATE_ANIMATION,
MapMarkerAnimation.ALPHA_ANIMATION,
MapMarkerAnimation.SCALE_ANIMATION,
MapMarkerAnimation.SINGLE_SCALE_ANIMATION,
MapMarkerAnimation.ANIMATION_SET);
} else if (id == R.id.demoAnimation) {
flags = Arrays.asList(
MapMarkerAnimation.DEMO_GROW_ANIMATION,
MapMarkerAnimation.DEMO_JUMP_ANIMATION,
MapMarkerAnimation.DEMO_BREATHE_ANIMATION);
} else {
return;
}
mapMarkerAnimation.setFlags(flags);
}
运行效果图
标签: 动画 ,
示例 ,
float ,
ANIMATION ,
animation ,
new ,
Android ,
Animation ,
高德
From: https://blog.csdn.net/kikikiki001/article/details/141506298