场景:
需要在地图定位点添加一个向外扩散的水波纹效果。如图
问题:
如何实现在一个点添加一个向外扩散的动画?
实现方案:
解决思路:首先看下高德地图的demo,该demo展示了在3D地图上如何实现定位圈向外扩展的动画效果。但是无法实现图上的效果。
https://lbs.amap.com/dev/demo/location-circle#Android
我们的思路是,添加多个圆,然后间隔执行扩散动画。即可实现图上的效果。
第一步:创建一个工具类,复制以下代码到创建的工具类
private List<Circle> circleList;//圆集合
private ValueAnimator valueAnimator;//动画工具
/**
* 添加水波纹效果
*
* @param latLng 要展示扩散效果的点经纬度
* AMap aMap:高德地图
*/
public void addWaveAnimation(LatLng latLng, AMap aMap) {
circleList = new ArrayList<>();
int radius = 50;
for (int i = 0; i < 4; i++) {
radius = radius + 50 * i;
circleList.add(CircleBuilder.addCircle(latLng, radius, aMap));
}
valueAnimator = AnimatorUtil.getValueAnimator(0, 50, new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int value = (int) animation.getAnimatedValue();
for (int i = 0; i < circleList.size(); i++) {
int nowradius = 50 + 50 * i;
Circle circle = circleList.get(i);
double radius1 = value + nowradius;
circle.setRadius(radius1);
int strokePercent = 200;
int fillPercent = 20;
if (value < 25) {
strokePercent = value * 8;
fillPercent = value * 20 / 50;
} else {
strokePercent = 200 - value * 4;
fillPercent = 20 - value * 20 / 50;
}
if (circle.getFillColor() != CircleBuilder.getStrokeColor(strokePercent)) {
circle.setStrokeColor(CircleBuilder.getStrokeColor(strokePercent));
circle.setFillColor(CircleBuilder.getFillColor(fillPercent));
}
}
}
});
}
/**
* 移除水波纹动画
*/
public void removeCircleWave() {
if (null != valueAnimator) {
valueAnimator.cancel();
}
if (circleList != null) {
for (Circle circle : circleList) {
circle.remove();
}
circleList.clear();
}
}
**第二步:**创建一个画圆的工具类,复制下面的代码到自己的项目中
public class CircleBuilder {
//180, 3, 145, 255
//10, 0, 0, 180
public static final int STROKE_COLOR = Color.argb(180, 3, 145, 200);
public static final int FILL_COLOR = Color.argb(10, 0, 0, 180);
//224,236,237
//233,241,242
public static Circle addCircle(LatLng latlng, double radius, AMap aMap) {
CircleOptions options = new CircleOptions();
options.strokeWidth(1f);
options.fillColor(FILL_COLOR);
options.strokeColor(STROKE_COLOR);
options.center(latlng);
options.radius(radius);
return aMap.addCircle(options);
}
public static int getStrokeColor(int alpha) {
return Color.argb(alpha, 3, 145, 200);
}
public static int getFillColor(int alpha) {
return Color.argb(alpha, 0, 0, 180);
}
}
第三步:
在需要添加水波纹动画的地方调用addWaveAnimation方法。添加经纬度和AMap对象。
在需要取消水波纹动画的地方调用removeCircleWave方法即可。
大功告成!
好多小伙伴留言需要动画工具类,现在添加到下面
**
* Description:AnimatorUtil 动画工具类
*/
public class AnimatorUtil {
private static AnimatorUtil animatorUtil;
public static AnimatorUtil getInstance() {
if (animatorUtil == null) {
animatorUtil = new AnimatorUtil();
}
return animatorUtil;
}
/**
* View缩放动画
*
* @param view
* @param time
* @param count
*/
public void scaleViewAnimator(View view, int time, int count) {
ScaleAnimation scaleAnimation = new ScaleAnimation(0, 1, 0, 1, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
scaleAnimation.setDuration(time);
scaleAnimation.setRepeatCount(count);
scaleAnimation.setFillAfter(true);
view.startAnimation(scaleAnimation);
}
public static ValueAnimator getValueAnimator(int min, int max, ValueAnimator.AnimatorUpdateListener animatorUpdateListener) {
ValueAnimator valueAnimator = ValueAnimator.ofInt(min, max);
valueAnimator.setDuration(3000);
valueAnimator.setInterpolator(new LinearInterpolator());
valueAnimator.addUpdateListener(animatorUpdateListener);
//无限循环
valueAnimator.setRepeatCount(ValueAnimator.INFINITE);
//从头开始动画
valueAnimator.setRepeatMode(ValueAnimator.RESTART);
valueAnimator.start();
return valueAnimator;
}