【达内课程】酷跑项目:模拟路线和显示数据

1、酷跑项目:崩溃自动重启功能
2、酷跑项目:首页跳转+底部菜单联动
3、酷跑项目:百度地图获取定位

实现倒计时功能
在这里插入图片描述
fragment_sport.xml中放置一个按钮,点击按钮实现倒计时功能

SportFragment中关键代码如下

    int count = 3;
    AlertDialog alertDialog;
    Handler handler = new Handler();
    private TextView tvAction;

	@Override
    public void onClick(View view) {
        switch (view.getId()){
        	//点击图中按钮实现倒计时
            case R.id.relativeLayout_startSport:
                alertDialog = new AlertDialog.Builder(getActivity()).create();
                View dialogView = View.inflate(getActivity(),R.layout.activity_show_counter,null);
                tvAction = dialogView.findViewById(R.id.tv_show_count);
                alertDialog.setView(dialogView);

                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        count--;
                        if(count<1){
                            alertDialog.dismiss();
                            alertDialog = null;
                            count = 3;
                        }else {
                            tvAction.setText(String.valueOf(count));
                            handler.postDelayed(this,1000);
                        }
                    }
                },1000);

                alertDialog.show();
                break;
        }
    }

其中activity_show_counter是弹出的倒计时的布局

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" 
    android:background="@color/title_bg_green"
    >

    <TextView
        android:layout_margin="96dp"
        android:id="@+id/tv_show_count"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:textSize="@dimen/text_count_size"
        android:textColor="@android:color/white"
        android:text="3" />

</RelativeLayout>

绘制

在这里插入图片描述
根据绘制线来完成绘制

    //放线的坐标
    ArrayList<LatLng> pointsList = new ArrayList<LatLng>();

	class MyLocationListener extends BDAbstractLocationListener {

        @Override
        public void onReceiveLocation(BDLocation bdLocation) {
          	......

            //在地图上单击
            mBaiduMap.setOnMapClickListener(new BaiduMap.OnMapClickListener() {
                @Override
                public void onMapClick(LatLng latLng) {
                    //之前单击绘制点的代码先注释掉
                    ......
                    
                    //用户在跑步,跑步时得到坐标,模拟得到坐标
                    mBaiduMap.clear();
                    pointsList.add(latLng);
                    //画线
                    if (pointsList.size() >= 2) {
                        //设置折线的属性
                        PolylineOptions mOverlayOptions = new PolylineOptions();
                        mOverlayOptions.points(pointsList);
                        //在地图上绘制折线
                        mBaiduMap.addOverlay(mOverlayOptions);
                    }
                }

                @Override
                public boolean onMapPoiClick(MapPoi mapPoi) {
                    return false;
                }
            });
        }
    }

显示数据
在这里插入图片描述

fragment_sport中引入fragment_sport_recorder

fragment_sport_recorder

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/linearLayout1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@android:color/white"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:orientation="vertical">

        <TextView
            android:id="@+id/tv_distance"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="0.00"
            android:textColor="@android:color/black"
            android:textSize="@dimen/text_recoder_distance_size" />

        <TextView
            android:id="@+id/textView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="距离(公里)"
            android:textColor="@android:color/black"
            android:textSize="@dimen/text_recoder_name_size" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="1px"
        android:background="@color/gray_normal"></LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/activity_bg"
        android:orientation="horizontal">

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:orientation="vertical">

            <Chronometer
                android:id="@+id/chronometer1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Chronometer" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="时长"
                android:textColor="@android:color/black"
                android:textSize="@dimen/text_recoder_name_size" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="1px"
            android:layout_height="match_parent"
            android:background="@color/gray_normal"
            android:orientation="vertical"></LinearLayout>

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:orientation="vertical">

            <TextView
                android:id="@+id/tv_recorder_speed"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="0.00"
                android:textColor="@android:color/black"
                android:textSize="@dimen/text_recoder_time_size" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="时速(公里/时)"
                android:textColor="@android:color/black"
                android:textSize="@dimen/text_recoder_name_size" />
        </LinearLayout>
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="1px"
        android:background="@color/gray_normal" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="@dimen/margin"
        android:background="@color/activity_bg" />
</LinearLayout>

SportFragment中关键代码

public class SportFragment extends Fragment implements View.OnClickListener {
	......
    //显示统计界面
    LinearLayout recorderLinearLayout;
    //更新统计数据
    Runnable updateDataRunnable;
    Chronometer chronometer;
	......
 @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.relativeLayout_startSport:
                alertDialog = new AlertDialog.Builder(getActivity()).create();
                View dialogView = View.inflate(getActivity(), R.layout.activity_show_counter, null);
                tvAction = dialogView.findViewById(R.id.tv_show_count);
                alertDialog.setView(dialogView);

                if (tvButton.getText().toString().equals("开始")) {

                    handler.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            count--;
                            if (count < 1) {
                                alertDialog.dismiss();
                                alertDialog = null;
                                count = 3;
                                tvButton.setText("结束");
                                showRecordder();
                            } else {
                                tvAction.setText(String.valueOf(count));
                                handler.postDelayed(this, 1000);
                            }
                        }
                    }, 1000);

                    alertDialog.show();
                }else if(tvButton.getText().toString().equals("结束")){
                    tvButton.setText("开始");
                    recorderLinearLayout.setVisibility(View.GONE);
                    pointsList.clear();
                    mBaiduMap.clear();
                    //前面执行handler.post(runnable)
                    //必须移除
                    handler.removeCallbacks(updateDataRunnable);
                }
                break;
        }
    }

    private void showRecordder() {
        recorderLinearLayout.setVisibility(View.VISIBLE);
        tvDistance.setText("0.00");
        tvRecorderSpeed.setText("0.00");

        chronometer.setBase(SystemClock.elapsedRealtime());
        chronometer.start();

        updateDataRunnable = new Runnable() {
            @Override
            public void run() {
                try {
                    if (pointsList.size() >= 2) {
                        //更新公里
                        double distance = 0;
                        //list[0] 112,39
                        //list[1] 113,39
                        //list[2] 114,39
                        for (int i = 0; i < pointsList.size() - 1; i++) {
                            double lon1 = pointsList.get(i).longitude;
                            double lat1 = pointsList.get(i).latitude;

                            double lon2 = pointsList.get(i + 1).longitude;
                            double lat2 = pointsList.get(i + 1).latitude;

                            distance = distance + BaiduMapUtil.GetDistance(lon1, lat1, lon2, lat2);
                        }
                        //算出的结果是米
                        distance = distance / 1000;
                        String strDistance = String.valueOf(distance);
                        //1.06839233
                        if (strDistance.contains(".")) {
                            int pointPosition = strDistance.indexOf(".");
                            strDistance = strDistance.substring(0, pointPosition + 3);
                        }
                        tvDistance.setText(strDistance);

                        //更新速度
                        String showTime = chronometer.getText().toString();
                        double hour = 0, minute = 0, second = 0;
                        String strMinute = showTime.split(":")[0];
                        minute = Double.parseDouble(strMinute);

                        String strSecond = showTime.split(":")[1];
                        second = Double.parseDouble(strSecond);

                        hour = (minute * 60 + second) / 60 / 60;

                        double speed = distance/hour;
                        String strSpeed = String.valueOf(speed);
                        //12.345
                        //.position 2
                        //0,5 保留2位
                        if(strSpeed.contains(".")){
                            int pointPosition = strSpeed.indexOf(".");
                            strSpeed = strSpeed.substring(0,pointPosition+3);
                        }

                        tvRecorderSpeed.setText(strSpeed);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    //再次调用run
                    handler.postDelayed(this, 2000);
                }
            }
        };
        //updateDataRunnable不停运行
        handler.post(updateDataRunnable);
    }

其中BaiduMapUtil是计算距离的工具类

public class BaiduMapUtil {
    static final double DEF_PI = 3.14159265359; // PI
    static final double DEF_2PI = 6.28318530712; // 2*PI
    static final double DEF_PI180 = 0.01745329252; // PI/180.0
    static final double DEF_R = 6370693.5; // radius of earth

    /**
     * 计算距离
     *
     * @param lon1
     * @param lat1
     * @param lon2
     * @param lat2
     * @return
     */
    public static double GetDistance
    (double lon1, double lat1, double lon2, double lat2) {
        double ew1, ns1, ew2, ns2;
        double dx, dy, dew;
        double distance;

        ew1 = lon1 * DEF_PI180;
        ns1 = lat1 * DEF_PI180;
        ew2 = lon2 * DEF_PI180;
        ns2 = lat2 * DEF_PI180;

        dew = ew1 - ew2;

        if (dew > DEF_PI)
            dew = DEF_2PI - dew;
        else if (dew < -DEF_PI)
            dew = DEF_2PI + dew;
        dx = DEF_R * Math.cos(ns1) * dew;
        dy = DEF_R * (ns1 - ns2);

        distance = Math.sqrt(dx * dx + dy * dy);
        return distance;
    }
}

?Android Chronometer

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值