1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > android 高德地图动画 Android 高德地图上自定义动画

android 高德地图动画 Android 高德地图上自定义动画

时间:2019-11-08 05:56:11

相关推荐

android 高德地图动画 Android 高德地图上自定义动画

高德提供了SmoothMoveMarkerAPI的调用,用于平滑移动,只需要给point点就好了

还有animation的封装,对

RotateAnimation,AlphaAnimation,ScaleAnimation,TranslateAnimation,都有基本的操作,对其还有AnimationSet进行组合操作

但是,我们有时候对动画的要求有点多,不仅限于这些。

比如,在地图上画一个车,让车沿着轨迹移动,车头向着前进方向

如果只需要上面的要求,没有其他的。SmoothMoveMarker应该能满足你的要求。

所以,我们这里就不仅限于这些,我们与android提供的属性动画相结合操作。(别问我属性动画是什么,百度,google,bing去)。

ok,说了这么多。先看看效果图。

车辆行驶沿着轨迹,并且根据行驶速度进行加速减速。

emmmmm,因为数据都是我瞎弄得不是真实值,所以有点误差,拿到真实值后需要reset一下。

下面开始操作吧,整个地图基于高德地图

###添加高德地图的依赖

请百度百科

###绘制轨迹

我们使用方法addPolyline就ok

整个绘制代码

/**

* 添加轨迹线

*

* @param points

*/

private void addPolylineInPlayGround(Listpoints) {

Listlist = new ArrayList<>();

for (int i = 0; i < points.size(); i++) {

list.add(new LatLng(points.get(i).getLat(), points.get(i).getLon()));

}

ListcolorList = new ArrayList();

ListbitmapDescriptors = new ArrayList();

int[] colors = new int[]{Color.argb(255, 0, 255, 0), Color.argb(255, 255, 255, 0), Color.argb(255, 255, 0, 0)};

//用一个数组来存放纹理

ListtextureList = new ArrayList();

textureList.add(BitmapDescriptorFactory.fromResource(R.drawable.custtexture));

ListtexIndexList = new ArrayList();

texIndexList.add(0);//对应上面的第0个纹理

texIndexList.add(1);

texIndexList.add(2);

Random random = new Random();

for (int i = 0; i < list.size(); i++) {

colorList.add(colors[random.nextInt(3)]);

bitmapDescriptors.add(textureList.get(0));

}

mPolyline = mAMap.addPolyline(new PolylineOptions().setCustomTexture(BitmapDescriptorFactory.fromResource(R.drawable.custtexture)) //setCustomTextureList(bitmapDescriptors)

.addAll(list)

.useGradient(true)

.width(18));

LatLngBounds.Builder builder = LatLngBounds.builder();

for (int i = 0; i < list.size() - 1; i++) {

builder.include(list.get(i));

} mAMap.animateCamera(CameraUpdateFactory.newLatLngBounds(builder.build(), 0));

ok,线我们添加进去了

这样操作的

//RxJava+Retrofit 了解一下,空了在贴

NetUtil.INSTANCE().create(new MySubscribe>() {

@Override

public void onNext(ListcarRoutes) {

//网络请求添加线

mList.addAll(carRoutes);

}

@Override

public void onComplete() {

addPolylineInPlayGround(mList);

}

}, id, true);

接着我们通过属性动画里的ValueAnimator设置我们的值如何变化

/**

* 动画效果

*/

public Animator setAnimation(final Marker marker, float duration) {

ValueAnimator animator;

Object[] objects = new Object[mList.size()];

for (int i = 0; i < objects.length; i++) {

objects[i] = mList.get(i);

}

animator = ValueAnimator.ofObject(new TypeEvaluator() {

@Override

public CarRoute evaluate(float fraction, CarRoute startValue, CarRoute endValue) {

double lat = startValue.getLat() + fraction * (endValue.getLat() - startValue.getLat());

double lon = startValue.getLon() + fraction * (endValue.getLon() - startValue.getLon());

//注意这里的speed没有用到,我懒得改了

return new CarRoute(lon, lat, speed, getAngle(startValue.getLatLng(), endValue.getLatLng()));

}

}, objects);

animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

@Override

public void onAnimationUpdate(ValueAnimator animation) {

CarRoute carRoute = (CarRoute) animation.getAnimatedValue();

marker.setMarkerOptions(marker.getOptions().position(carRoute.getLatLng()).rotateAngle((float) carRoute.getBearing()));

//默认无

//mAMap.moveCamera(CameraUpdateFactory.changeLatLng(carRoute.getLatLng()));

}

});

animator.setInterpolator(new SpeedInterpolator(mList, duration));

animator.setDuration((long) duration);

animator.start();

return animator;

}

比较正常的操作,接下来我们就可以看看我们效果

可以看到我们的marker点就在轨迹上平缓的移动,整体效果跟SmoothMoveMarker一样。

接着,车辆行驶过程中肯定有速度,有速度就有加速,减速,匀速。

那我们就可以根据这个来做一个加减速的行车动画,而不是全程匀速无聊。

所以这里我们就要用到插值器。关于插值器,可以百度,谷歌等看看用法,这里我们自定义自己的插值器。

public static class SpeedInterpolator implements TimeInterpolator {

private ListmSpeedList;

private double totalDistance;

SpeedInterpolator(ListspeedList, float duration) {

mSpeedList = speedList;

//真实距离

for (int i = 0; i < speedList.size() - 1; ++i) {

double k = (double) AMapUtils.calculateLineDistance(speedList.get(i).getLatLng(), speedList.get(i + 1).getLatLng());

this.totalDistance += k;

}

}

/**

* 完成度时间

*这里的input是系统计算返回的

* @param input 可看之为时间进行了多久

* 单位km/h 换算 m/s

* @return 可反映速度快慢的返回值

*/

@Override

public float getInterpolation(float input) {

}

}

大概样子是这个,接着我们需要在

getInterpolation() 里编写我们自己的逻辑

编写之前我们先画点图了解并思考我们如何操作

v-t 速度和时间

表示了v的变化,为了整个逻辑简洁,不考虑变加速,整个过程就是一个时间段内就是匀加速,匀减速或者匀速。所以可以看到6s内每1s,其加速度的值都是固定的

比如0-1 加速度为1

a-t 加速度和时间

啊,用excel画布来这图,将就看吧

s-t 路程和时间

好了三张图上完了。我们在了解一下fraction这个值

哪来的?

public CarRoute evaluate(float fraction, CarRoute startValue, CarRoute endValue)

这段话你忘了么。然后了解属性动画后知道这个值得范围是[0,1]

这个就可以理解为我们的完成度,完成了百分之多少我们的动画就该进行到哪了

那么这个值怎么来的?

就是插值器里return来的了

然后input这个值我们理解为系统返回的时间(系统按照duration比例转换的[0,1]时间)

ok,就是说 input可以理解为我们上图的t这个值。那么上面哪张图与完成最相似。没错,就是S-T图我们的路径与时间关系的图

在这里距离是9米,我们每行驶一段距离与总距离的比值就可以是我们返回的fraction这个值了。

接下来我们按照图来编写我们的公式。这里会有坑,请注意

首先回顾一下高中物理知识

匀速情况下

s=v*t

匀变速情况下

s=vt+at*t/2 a为加速度,为矢量值(问我矢量是什么的,棺材板压好了么)

然后这里有一个问题,速度是变化的如何知道哪一段是哪个速度呢?

所以我们加一个索引

int index = (int) (input * (mSpeedList.size() - 1));

if (index == mSpeedList.size() - 1) {

return 1;

}

float start = (float) (mSpeedList.get(index).getSpeed() / 3.6f);

ok,我们通过时间进行了多少判断出我们该取哪一个点的初始值

接下来进行计算

直接放代码吧

@Override

public float getInterpolation(float input) {

index = (int) (input * (mSpeedList.size() - 1));

if (index == mSpeedList.size() - 1) {

return 1;

}

float start = (float) (mSpeedList.get(index).getSpeed() / 3600 * 1000);

float end = (float) (mSpeedList.get(index + 1).getSpeed() / 3600 * 1000);

double a = (end - start) / t;//加速度

//通过一个temp指针得到现在的input的时候行进了多少距离

double c = input - temp;

temp = input;

//重新指向input的位置

s += v * c + a * c * c / 2;

v = (float) (v + a * c);//当前速度

//实际距离,真实距离 totalDistance

return (float) (s / (1181.0176983519816 * multiples));

}

来个手绘图描述一下上诉代码

不要介意

V0是我们temp指向的速度,V1是我们input指向的速度

v1 = v0 + a * t

这就是计算公式,同时根据v0==>>v1的时间变化

得出 > s = v0 * t + a * t * t / 2;

然后加上我们行走过的距离就能得到我们到input的时候走过的距离了。

末尾的1181.0176983519816是什么东西

是logcat打印出来的距离值,因为这只是我随便弄得值(才不会说是在高德上面一个一个点的),所以跟真实距离(totalDistance)有差距。

至于那个倍数,是针对于duration这个会翻倍的东东。(这个倍数请忽略,自我尝试才能知道最终结果)

ok,有什么疑问留下吧,欢迎大家一起探讨。

上面的插值器的代码有点问题(真的,不骗你们),我用另一种方式写了一下。需要的来这里

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。