基于高德SDK实现跑步时轨迹渐变功能

来源:互联网 发布:证券期货软件开发许可 编辑:程序博客网 时间:2024/05/22 15:58

今天在无意间翻看半年多前做的项目的时候,除了对自己当时写的渣代码的无尽嫌弃,更多是感叹当时在遇到困难时的种种不易,印象比较深刻的是在做重邮约跑的时候视觉要求做一个跑步时轨迹动态渐变的功能,并且采用均匀渐变,当时翻看高德SDK时候并没有发现相应的API,所以也是一脸懵逼,只能从颜色渐变的原理入手,逐步自己写一个工具类来实现了。
效果图如下:
轨迹渐变
虽然现在来看实现起来很简单,但还是把过程记录下来吧。

1.RGB的基本概念

RGB色彩模式是工业界的一种颜色标准,是通过对红(R)、绿(G)、蓝(B)三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色的,RGB即是代表红、绿、蓝三个通道的颜色,这个标准几乎包括了人类视力所能感知的所有颜色。
要想操作渐变轨迹,就只需操作RGB三种颜色的色值就行了。

2.渐变的公式

既然渐变有公式,那么大部分问题就迎刃而解了。

假设某个通道的色值从startColor渐变到endColor,渐变距离的总距离为totalDistance,每隔 i 距离计算一次渐变的色值,则渐变公式为:

gradient = endColor +(startColor - endColor)* i /totalDistance

那么,思路就很清晰了,每次返回经纬度的时候,就绘制一点轨迹,并利用公式计算出当前轨迹的色值,即可实现渐变的轨迹。
但是,问题又来了,在跑步的时候如何能够确定跑步的总距离?当然是没办法确定的,所以当时我想到了两种方案:
第一:多数学生跑步的距离不会超过20km,就强行把totalDistance设置成20km。
第二:将渐变颜色的距离设得稍微短一点,如500米,然后采用“startColor -> endColor -> startColor -> endColor -> …”这种交替渐变的方案,实现渐变过渡。
最终综合了实际显示效果的因素,我方案二。

3.具体实现

具体实现比较简单,只需要每次动态调用GradientHelper#getGradient,便可动态确定当前位置的颜色值。

import android.graphics.Color;import android.util.Log;import java.util.ArrayList;/** * Created by xushuzhan on 2017/3/15. */public class GradientHelper {    private static final String TAG = "GradientHelper";    public int i= -1;    public List<RGB> gradient=new ArrayList<>();    int totalDistance;//渐变的范围    int startColor;//渐变的起始颜色    int endColor;//渐变的结束颜色    public GradientHelper(int totalDistance, int startColor, int endColor) {        this.totalDistance = totalDistance;        this.startColor = startColor;        this.endColor = endColor;    }    /**     * 获取当前渐变颜色     * @return 当前颜色的RGB值     */    public int getGradient() {        i++;        int gradient_R ;        int gradient_G ;        int gradient_B ;        int delta_R = Color.red(startColor) - Color.red(endColor);        int delta_G = Color.green(startColor) - Color.green(endColor);        int delta_B = Color.blue(startColor) - Color.blue(endColor);        if (i <= totalDistance) {            gradient_R = Color.red(endColor) + delta_R * i / totalDistance;            gradient_G = Color.green(endColor)  + delta_G * i / totalDistance;            gradient_B = Color.blue(endColor)  + delta_B * i / totalDistance;            gradient.add(new RGB(gradient_R,gradient_G,gradient_B));        } else if (i <= totalDistance*2 +1) {            RGB rgb_1 = gradient.get(gradient.size() - i % (totalDistance + 1) -1);            gradient_R = rgb_1.gradient_R;            gradient_G = rgb_1.gradient_G;            gradient_B = rgb_1.gradient_B;        } else {            RGB rgb_2 = gradient.get(0);            gradient_R = rgb_2.gradient_R;            gradient_G = rgb_2.gradient_R;            gradient_B = rgb_2.gradient_R;            gradient.clear();            i = -1;        }        return Color.argb(255,gradient_R,gradient_G,gradient_B);    }    class RGB{        int gradient_R ;        int gradient_G ;        int gradient_B ;        public RGB(int gradient_R, int gradient_G, int gradient_B) {            this.gradient_R = gradient_R;            this.gradient_G = gradient_G;            this.gradient_B = gradient_B;        }    }}

将过程色彩全部计算并储存在集合gradient中,调用时只需要在包含RGB三个值的集合里面来回读取即可。
调用的时候:

int distance = 1000;//1000米int startColor = Color.argb(255, 135, 81, 168);int endColor = Color.argb(255, 246, 100, 135);GradientHelper gradientHelper = new GradientHelper(distance,startColor,endColor);for (int j = 0; j < distance; j++) {    //当前颜色颜色的RGB值    int colorRGB = gradientHelper.getGradient();}

使用高德地图的SDK的时候像如下方法这样使用,即可在跑步时实现动态显示渐变轨迹。

    //实例化渐变帮助类    GradientHelper mGradientHelper = new GradientHelper(500, Config.startColor, Config.endColor)    @Override   public void onLocationChanged(AMapLocation aMapLocation) {        if (mListener != null && aMapLocation != null) {            mListener.onLocationChanged(aMapLocation);// 显示系统小蓝点            //当前的经纬度            LatLng newLatLng = new LatLng(aMapLocation.getLatitude(), aMapLocation.getLongitude());            if (aMapLocation.getAccuracy() <= 30f && aMapLocation.getAccuracy() > 0) {                //判断是否为第一次定位经纬度                if (isFirstRecord) {                    mAMap.moveCamera(CameraUpdateFactory.zoomTo(18));  //设置缩放级别                    oldLatLng = newLatLng;                    isFirstRecord = false;                    //开始定位的时间,之后会放在开始跑步的方法里                } else if (mPathRecord == null) {                    oldLatLng = newLatLng;                    mPathRecord = new PathRecord();                    mPathRecord.setBeginTime(Utils.getTimestamp());                } else if (!Utils.isLatLngEqual(oldLatLng, newLatLng)) { //如果位置有移动                    PolylineOptions polylineOptions = new PolylineOptions();                    polylineOptions.width(15);                    //设置渐变颜色                    polylineOptions.color(mGradientHelper.getGradient());                    polylineOptions.add(oldLatLng, newLatLng);                    oldLatLng = newLatLng;                    mAMap.addPolyline(polylineOptions);                    //当前跑的距离                    mDistance = Utils.getDistanceByLatLng(mPathRecord.getRunningLatLng());                }            }        }    }
原创粉丝点击