轨迹播放


首先上视频效果(本来是要弄成GIF动态图的,但是手机将图片用微信发到电脑,电脑修改后缀名后还是不能展示)

完整代码在最后面

在实现前需要先初始化和定义一些变量(大佬可以直接跳过),坐标列表和起点以及终点坐标根据各自的真实情况去赋值,这里就不显示了。

//获取的坐标列表
    private List<LatLng> points;
    //起点和终点坐标--用于给起点和终点做标记,不需要可以去掉
    private LatLng latLngStart, latLngEnd;

    private MapView mMapView = null;//xml布局的地图控件
    private AMap aMap;//高德地图map

    private ImageView mPlayBtn;//播放暂停按钮
    private SeekBar mProgressBar;//进度条

    boolean isFirstMove = true;//是否首次移动
    boolean isPlay = true;//是否正在移动
    private SmoothMoveMarker smoothMoveMarker;//控制车辆运动的对象
    private int current;//当前滑动到的值
    private int poiSize;//记录轨迹数据的数量--用于设计进度条的大小
    private double totalTime;//轨迹总时间--用于设计进度条的总时间,可以自己设置固定值


    private Timer timer;//计时器,用于控制进度条自动滑动

    //onCreate方法就不说明了

    private void initView() {
        //高德地图所需的配置
        ServiceSettings.updatePrivacyShow(getContext(), true, true);
        ServiceSettings.updatePrivacyAgree(getContext(), true);
        mMapView = (MapView) findViewById(R.id.mapView);//地图组件
        //在activity执行onCreate时执行mMapView.onCreate(savedInstanceState),创建地图
        mMapView.onCreate(savedInstanceState);
        aMap = mMapView.getMap();

        mPlayBtn = findViewById(R.id.play_btn);//播放按钮
        mProgressBar = findViewById(R.id.progress_bar);//进度条

        //是否第一次显示,是则初始化数据
        if (isFirstMove)
            initData();//该方法用于获取轨迹的列表值,在这里给points赋值

        //赋值-points为轨迹点列表
        latLngStart = points.get(0);//起点坐标
        latLngEnd = points.get(points.size() - 1);//终点坐标
        poiSize = points.size();//记录总数量
        totalTime = ((double) poiSize) / 30;//记录总时间
        mProgressBar.setMax(poiSize);//进度条设置最大值
        setMap();//设置地图的方法

        initListener();//点击事件函数
    }

    //下面的地图根据生命周期的配置
     @Override
    public void onResume() {
        super.onResume();
        //在activity执行onResume时执行mMapView. onResume (),实现地图生命周期管理
        mMapView.onResume();
    }

    @Override
    public void onPause() {
        super.onPause();
        //在activity执行onPause时执行mMapView. onPause (),实现地图生命周期管理
        mMapView.onPause();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        //在activity执行onDestroy时执行mMapView.onDestroy(),实现地图生命周期管理
        mMapView.onDestroy();
    }

    @Override
    public void onSaveInstanceState(@NonNull Bundle outState) {
        super.onSaveInstanceState(outState);
        //在activity执行onSaveInstanceState时执行mMapView.onSaveInstanceState (outState),保存地图当前的状态
        mMapView.onSaveInstanceState(outState);
    }

下面写setMap()方法,主要是定位到起点,绘制起点和终点的标记和绘制轨迹线。

private void setMap() {
        //定位到起点--latLngStart为起点坐标,12为图层,控制地图比例,可以自己根据需要修改
        CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(latLngStart, 12);
        aMap.moveCamera(cameraUpdate);

        //绘制起点的标记
        MarkerOptions startOptions = new MarkerOptions();
        BitmapDescriptor startBit = BitmapDescriptorFactory.fromResource(R.drawable.icon_start);//起点坐标图片
        startOptions.position(latLngStart).icon(startBit);
        aMap.addMarker(startOptions);

        //绘制终点的标记
        MarkerOptions endOptions = new MarkerOptions();
        BitmapDescriptor endBit = BitmapDescriptorFactory.fromResource(R.drawable.icon_end);//终点坐标图片
        endOptions.position(latLngEnd).icon(endBit);
        aMap.addMarker(endOptions);

        //绘制轨迹线--points轨迹点列表,5-线的宽度,0xAAFFC107为16进制的颜色
        PolylineOptions lineOptions = new PolylineOptions().addAll(points).width(5).color(0xAAFFC107);
        Polyline polyline = aMap.addPolyline(lineOptions);

        //轨迹动画方法--points为轨迹点列表,true为设置是否要让小车动起来
        setStartAnimation(points, true);
    }

setStartAnimation(points, true);方法,用于控制小车运动和进度条移动

//points轨迹点列表,isMove设置是否播放
    private void setStartAnimation(List<LatLng> points, boolean isMove) {
        //如果不为空说明以及有轨迹播放了,将原来的轨迹清除
        if (smoothMoveMarker != null) {
            smoothMoveMarker.stopMove();
            smoothMoveMarker.removeMarker();
        }
        //若计时器不为空则清除,再重新设定计时器--自定义的函数,实现方法放在后面
        stopTimer();

        //设置滑动的图标
        smoothMoveMarker = new SmoothMoveMarker(aMap);
        smoothMoveMarker.setDescriptor(BitmapDescriptorFactory.fromResource(R.drawable.icon_truck));//里面为小车的图片,可以自己选图片

        LatLng drivePoint = points.get(0);
        Pair<Integer, LatLng> pair = SpatialRelationUtil.calShortestDistancePoint(points, drivePoint);
        points.set(pair.first, drivePoint);
        List<LatLng> subList = points.subList(pair.first, points.size());

        //设置滑动的轨迹左边点
        smoothMoveMarker.setPoints(subList);
        //设置滑动的总时间,current为点击进度条时记录的数值,然后根据数值计算前面的部分所占比例
        double cur = ((double) current) / poiSize;
        smoothMoveMarker.setTotalDuration((int) (totalTime * (1 - cur) + 0.5));
        //如果需要播放再开启计时器,计时器开启则会移动进度条
        if (isMove) {
            //开启计时器--自定义的函数,实现方法放在后面
            startTimer();
            //开始滑动小车,轨迹播放开始
            smoothMoveMarker.startSmoothMove();
            //将播放按钮的图片改为暂停图标
            mPlayBtn.setBackground(getResources().getDrawable(R.drawable.icon_pause_video));
            isPlay = true;//将播放状态设置为true
        } else {
            //将播放按钮的图片改为播放图标
            mPlayBtn.setBackground(getResources().getDrawable(R.drawable.icon_play_video));
            isPlay = false;//将播放状态设置为false
        }
    }

接下来说明开启计时器和暂停计时器的方法start Timer()和stop Timer()

/**
     * 开启计时方法
     */
    public void startTimer() {
        timer = new Timer();
        TimerTask task = new TimerTask() {
            @Override
            public void run() {
                mProgressBar.setProgress(mProgressBar.getProgress() + 3);
            }
        };
        timer.schedule(task, 100, 100);
    }

    /**
     * 暂停计时方法
     */
    public void stopTimer() {
        if (timer != null) {
            timer.cancel();
            timer = null;
        }
    }

最后一步,点击事件方法 initListener()

/**
     * 点击事件
     */
    private void initListener() {
        //播放监听
        mPlayBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (isPlay) {//如果正在播放则变为暂停
                    smoothMoveMarker.stopMove();
                    isPlay = !isPlay;
                    //将播放按钮的图标改为播放图标
                    mPlayBtn.setBackground(getResources().getDrawable(R.drawable.icon_play_video));
                    //暂停计时器
                    stopTimer();
                } else {//如果播放暂停则开始播放
                    smoothMoveMarker.startSmoothMove();
                    isPlay = !isPlay;
                    //将播放按钮的图标改为暂停图标
                    mPlayBtn.setBackground(getResources().getDrawable(R.drawable.icon_pause_video));
                    //开启计时器
                    startTimer();
                }
            }
        });

        //进度条监听
        mProgressBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean b) {
                //progress当前进度值--当进度条的数值改变时就会调用该方法
                current = progress;//记录当前值
                if (current == poiSize) {//如果当前值为最大值,则将进度条清零,轨迹暂停
                    mProgressBar.setProgress(0);
                    setStartAnimation(points, false);
                }
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                //点击了进度条
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                //停止点击进度条
                //newpoints用于保存点击进度条后剩余轨迹的轨迹点列表
                List<LatLng> newpoints = new ArrayList<>();
                //计算点击后要跳过的部分所占总长的比例
                double cur = ((double) current) / poiSize;
                //根据比例计算起点值,如果总长是根据轨迹点的数量设定的,可以直接 i=current
                for (int i =  (int) (cur * points.size()); i< points.size(); i++) {
                    newpoints.add(points.get(i));
                }
                //如果剩余轨迹不为空且长度不为0则开启播放
                if (newpoints != null && newpoints.size() > 0) {
                    setStartAnimation(newpoints, true);
                }
            }
        });
    }

总体就是这样吧,一个效果自己弄了三天,一开始用百度地图,但是里面斜率和小车的旋转角度什么的得自己计算,我感觉会比较麻烦,于是转为高德,不需要去计算这些,感觉会方便一些,由于没有单独弄出来demo,所以没有单独发到git,但是注释以及很详细了,后续有需要可以整合到git上发布。

附上完整代码(功能在fragment中,可以根据自己需要改为Activity)

首先是xml布局(图片就自己去网上找吧iconfont-阿里巴巴矢量图标库) 

fragment_new.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <com.amap.api.maps.MapView
        android:id="@+id/mapView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <!--进度控制-->
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:layout_alignParentBottom="true"
        android:background="@color/black"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        android:layout_marginBottom="10dp"
        android:alpha="0.5"/>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:layout_alignParentBottom="true"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        android:layout_marginBottom="10dp">

        <ImageView
            android:id="@+id/play_btn"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:layout_centerVertical="true"
            android:layout_marginLeft="15dp"
            android:background="@drawable/icon_play_video"
            android:scaleType="fitXY" />

        <SeekBar
            android:id="@+id/progress_bar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:maxHeight="3dp"
            android:minHeight="3dp"
            android:paddingLeft="10dp"
            android:paddingRight="10dp"
            android:min="0"
            android:progressDrawable="@drawable/layer_list_seekbar"
            android:thumb="@drawable/icon_round"
            android:layout_toRightOf="@+id/play_btn"
            android:layout_centerVertical="true"/>
    </RelativeLayout>
</RelativeLayout>

进度条的drawable: layer_list_seekbar.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@android:id/background">
        <shape>
            <corners android:radius="3dp" />
            <!--<gradient-->
            <!--android:angle="270"-->
            <!--android:centerColor="#2B2B2B"-->
            <!--android:centerY="0.75"-->
            <!--android:endColor="#ff747674"-->
            <!--android:startColor="#ff9d9e9d" />-->
            <solid android:color="#ffffff" />
        </shape>
    </item>

    <item android:id="@android:id/progress">
        <clip>
            <shape>
                <corners android:radius="3dp" />
                <!--<gradient-->
                <!--android:angle="270"-->
                <!--android:centerColor="#ff3399CC"-->
                <!--android:centerY="0.75"-->
                <!--android:endColor="#ff6699CC"-->
                <!--android:startColor="#ff0099CC" />-->
                <solid android:color="#2496F6" />
            </shape>
        </clip>
    </item>
</layer-list>

页面逻辑:NewFragment.java

(这里继承的BaseFragment不用理会,自行改为Fragment或者Activity就行)

import android.content.Context;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.SeekBar;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.amap.api.maps.AMap;
import com.amap.api.maps.CameraUpdate;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.MapView;
import com.amap.api.maps.model.BitmapDescriptor;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.LatLngBounds;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.maps.model.Polyline;
import com.amap.api.maps.model.PolylineOptions;
import com.amap.api.maps.utils.SpatialRelationUtil;
import com.amap.api.maps.utils.overlay.SmoothMoveMarker;
import com.amap.api.services.core.ServiceSettings;

import org.ismarter.zhjt.R;
import org.ismarter.zhjt.base.BaseFragment;
import org.ismarter.zhjt.electronicwaybill.bean.WayBillTrackBean;
import org.ismarter.zhjt.util.MyGson;
import org.ismarter.zhjt.web.CallBackUtil;
import org.ismarter.zhjt.web.OkhttpUtil;
import org.ismarter.zhjt.web.WebConfig;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

import okhttp3.Call;

public class NewFragment extends BaseFragment{
    private String carNumber;
    private String waybillNo;
    //获取的坐标列表
    private List<LatLng> points;
    //起点和终点坐标
    private LatLng latLngStart, latLngEnd;

    private MapView mMapView = null;
    private AMap aMap;

    private ImageView mPlayBtn;//mPlayBtn
    private SeekBar mProgressBar;//mProgressBar

    boolean isFirstMove = true;//是否首次移动
    boolean isPlay = true;//是否正在移动
    private SmoothMoveMarker smoothMoveMarker;
    private int current;//当前滑动到的值
    private int poiSize;//记录轨迹数据的数量
    private double totalTime;//轨迹总时间

    private Timer timer;

    public NewFragment(String carNumber, String waybillNo) {
        this.carNumber = carNumber;
        this.waybillNo = waybillNo;
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_new, parent, false);
        initView(view, savedInstanceState);
        return view;
    }

    private void initView(View view, Bundle savedInstanceState) {
        ServiceSettings.updatePrivacyShow(getContext(), true, true);
        ServiceSettings.updatePrivacyAgree(getContext(), true);
        mMapView = (MapView) view.findViewById(R.id.mapView);
        //在activity执行onCreate时执行mMapView.onCreate(savedInstanceState),创建地图
        mMapView.onCreate(savedInstanceState);
        aMap = mMapView.getMap();

        mPlayBtn = view.findViewById(R.id.play_btn);
        mProgressBar = view.findViewById(R.id.progress_bar);

        initListener();
    }

    /**
     * 开启计时方法
     */
    public void startTimer() {
        timer = new Timer();
        TimerTask task = new TimerTask() {
            @Override
            public void run() {
                mProgressBar.setProgress(mProgressBar.getProgress() + 3);
            }
        };
        timer.schedule(task, 100, 100);
    }

    /**
     * 暂停计时方法
     */
    public void stopTimer() {
        if (timer != null) {
            timer.cancel();
            timer = null;
        }
    }

    /**
     * 点击事件
     */
    private void initListener() {
        //播放监听
        mPlayBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (isPlay) {
                    smoothMoveMarker.stopMove();
                    isPlay = !isPlay;
                    mPlayBtn.setBackground(getResources().getDrawable(R.drawable.icon_play_video));
                    //暂停计时器
                    stopTimer();
                } else {
                    smoothMoveMarker.startSmoothMove();
                    isPlay = !isPlay;
                    mPlayBtn.setBackground(getResources().getDrawable(R.drawable.icon_pause_video));
                    //开启计时器
                    startTimer();
                }
//                mProgressBar.setProgress(20);
            }
        });

        //进度监听
        mProgressBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean b) {
                //progress当前进度值
                current = progress;
                Log.e("aaaaaaa", current + "");
                if (current == poiSize) {
                    mProgressBar.setProgress(0);
                    setStartAnimation(points, false);
                }
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                //点击了进度条
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                //停止点击进度条
                List<LatLng> newpoints = new ArrayList<>();
                double cur = ((double) current) / poiSize;
                for (int i =  (int) (cur * points.size()); i< points.size(); i++) {
                    newpoints.add(points.get(i));
                }
                if (newpoints != null && newpoints.size() > 0) {
                    setStartAnimation(newpoints, true);
                }
            }
        });
    }

    @Override
    protected void onVisible() {
        super.onVisible();
        if (isFirstMove)
            initData();
        else {
//            smoothMoveMarker.destroy();
//            smoothMoveMarker.startSmoothMove();
        }
    }

    /**
     * 网络请求的轨迹数据,这里的动画时间是根据轨迹点的数量设定的,可以自己设置固定值
    **/
    private void initData() {
        Map<String, String> map = new HashMap<>();
        map.put("carNumber", carNumber);
        map.put("waybillNo", waybillNo);
        OkhttpUtil.okHttpPostJson(WebConfig.electronicWaybilltrack, MyGson.mapToJson(map), new CallBackUtil.CallBackString() {
            @Override
            public void onFailure(Call call, Exception e) {

            }

            @Override
            public void onResponse(String response) {
                if (!TextUtils.isEmpty(response)) {
                    WayBillTrackBean bean = MyGson.GsonToBean(response, WayBillTrackBean.class);
                    if (bean != null) {
                        //轨迹列表
                        List<WayBillTrackBean.VehicleHistoryListBean> beans = bean.vehicleHistoryList;
                        if (beans != null && beans.size() > 0) {
                            points = new ArrayList<>();
                            for (int i = 0; i < beans.size(); i++) {
                                LatLng latLng = new LatLng(beans.get(i).lat, beans.get(i).lon);
                                points.add(latLng);
                            }
                            if (points != null && points.size() > 0) {
                                latLngStart = points.get(0);
                                latLngEnd = points.get(beans.size() - 1);
                                poiSize = points.size();//记录总数量
                                totalTime = ((double) poiSize) / 30;//记录总时间
                                mProgressBar.setMax(poiSize);
                                setMap();
                            }
                        }
                        //告警地点列表
                        List<WayBillTrackBean.AlarmInfoListBean> alarmBeans = bean.alarmInfoList;
                        setAlarmPoint(alarmBeans);
                    } else {
                        Log.e("aaaaaaa", "空数据");
                    }
                }
            }
        });
    }

    /**
     * 设置警告点
     * @param alarmBeans:警告点坐标列表数据
     */
    private void setAlarmPoint(List<WayBillTrackBean.AlarmInfoListBean> alarmBeans) {
        if (alarmBeans != null && alarmBeans.size() > 0) {
            ArrayList<MarkerOptions> options = new ArrayList<>();
            for (int i = 0; i < alarmBeans.size(); i++) {
                LatLng latLng = new LatLng(Double.parseDouble(alarmBeans.get(i).y2d), Double.parseDouble(alarmBeans.get(i).x2d));
                MarkerOptions option = new MarkerOptions();
                BitmapDescriptor descriptor = BitmapDescriptorFactory.fromResource(R.drawable.icon_alarm_png);
                option.position(latLng).icon(descriptor);
                options.add(option);
            }
            if (options != null && options.size() > 0) {
                aMap.addMarkers(options, false);
            } else {
            }
        } else {
        }
    }

    private void setMap() {
        //定位到起点
//        CameraPosition cameraPosition = new CameraPosition(latLngStart, 13, 0, 30);
        CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(latLngStart, 12);
        aMap.moveCamera(cameraUpdate);

        //绘制起点的标记
        MarkerOptions startOptions = new MarkerOptions();
        BitmapDescriptor startBit = BitmapDescriptorFactory.fromResource(R.drawable.icon_start);
        startOptions.position(latLngStart).icon(startBit);
        aMap.addMarker(startOptions);

        //绘制终点的标记
        MarkerOptions endOptions = new MarkerOptions();
        BitmapDescriptor endBit = BitmapDescriptorFactory.fromResource(R.drawable.icon_end);
        endOptions.position(latLngEnd).icon(endBit);
        aMap.addMarker(endOptions);

        //绘制轨迹线
        PolylineOptions lineOptions = new PolylineOptions().addAll(points).width(5).color(0xAAFFC107);
        Polyline polyline = aMap.addPolyline(lineOptions);

        //轨迹动画
        setStartAnimation(points, true);
    }

    /**
     * 轨迹动画
     */
    private void setStartAnimation(List<LatLng> points, boolean isMove) {
        if (smoothMoveMarker != null) {
            smoothMoveMarker.stopMove();
            smoothMoveMarker.removeMarker();
        }
        //若计时器不为空则清除,再重新设定计时器
        stopTimer();

        //设置滑动的图标
        smoothMoveMarker = new SmoothMoveMarker(aMap);
        smoothMoveMarker.setDescriptor(BitmapDescriptorFactory.fromResource(R.drawable.icon_truck));

        LatLng drivePoint = points.get(0);
        Pair<Integer, LatLng> pair = SpatialRelationUtil.calShortestDistancePoint(points, drivePoint);
        points.set(pair.first, drivePoint);
        List<LatLng> subList = points.subList(pair.first, points.size());

        //设置滑动的轨迹左边点
        smoothMoveMarker.setPoints(subList);
        //设置滑动的总时间
        double cur = ((double) current) / poiSize;
        smoothMoveMarker.setTotalDuration((int) (totalTime * (1 - cur) + 0.5));
        if (isMove) {
            //开启计时器
            startTimer();
            //开始滑动
            smoothMoveMarker.startSmoothMove();
            mPlayBtn.setBackground(getResources().getDrawable(R.drawable.icon_pause_video));
            isPlay = true;
        } else {
            mPlayBtn.setBackground(getResources().getDrawable(R.drawable.icon_play_video));
            isPlay = false;
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        //在activity执行onResume时执行mMapView. onResume (),实现地图生命周期管理
        mMapView.onResume();
    }

    @Override
    public void onPause() {
        super.onPause();
        //在activity执行onPause时执行mMapView. onPause (),实现地图生命周期管理
        mMapView.onPause();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
//        mBaiduMap.setMyLocationEnabled(false);
        //在activity执行onDestroy时执行mMapView.onDestroy(),实现地图生命周期管理
        mMapView.onDestroy();
    }

    @Override
    public void onSaveInstanceState(@NonNull Bundle outState) {
        super.onSaveInstanceState(outState);
        //在activity执行onSaveInstanceState时执行mMapView.onSaveInstanceState (outState),保存地图当前的状态
        mMapView.onSaveInstanceState(outState);
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if (!getUserVisibleHint() && smoothMoveMarker != null) {
            smoothMoveMarker.stopMove();
//            smoothMoveMarker.removeMarker();
            isFirstMove = false;
            stopTimer();
            mPlayBtn.setBackground(getResources().getDrawable(R.drawable.icon_play_video));
            isPlay = false;
        }
    }
}