⑥ 步行路线详情
上面我们写好了四种出行方式的路线规划,并且一一做了测试,但是还有一个问题,就是不知道具体的路线信息,称之为路线规划详情。因此下面来介绍这个详情信息是怎么样显示的。因为这个路线详情涉及的内容比较多,所以我这里一个一个来写,首先是步行路线详情。
打开activity_route.xml,在里面增加如下布局代码:
代码语言:txt复制 <!--底部规划时间详情-->
<RelativeLayout
android:id="@ id/bottom_layout"
android:layout_width="match_parent"
android:layout_height="70dp"
android:layout_alignParentBottom="true"
android:background="#FFF"
android:orientation="horizontal"
android:padding="5dp"
android:visibility="gone">
<TextView
android:id="@ id/tv_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginStart="12dp"
android:layout_weight="1"
android:paddingEnd="12dp"
android:singleLine="true"
android:textColor="#333333"
android:textSize="16sp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginEnd="10dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:text="详情"
android:textColor="#4c90f9"
android:textSize="14sp" />
<Button
android:layout_width="7dp"
android:layout_height="13dp"
android:layout_marginStart="4dp"
android:background="@mipmap/arrow_right_blue"
android:gravity="center_vertical" />
</LinearLayout>
</RelativeLayout>
添加位置如下:
没有的图标去我的源码里面找,或者去高德的SDKdemo里面去找。下面进入到RouteActivity,
代码语言:txt复制 //路线规划详情
private RelativeLayout bottomLayout;
//花费时间
private TextView tvTime;
然后绑定控件iD,在initTravelMode方法中。
下面要显示步行花费的时间,找到onWalkRouteSearched方法,在里面增加如下代码:
代码语言:txt复制 //显示步行花费时间
tvTime.setText(des);
bottomLayout.setVisibility(View.VISIBLE);
//跳转到路线详情页面
bottomLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(RouteActivity.this,
RouteDetailActivity.class);
intent.putExtra("type",0);
intent.putExtra("path", walkPath);
startActivity(intent);
}
});
添加位置如下图:
这里我把之前的日志打印去掉了,换成文本显示,你会看到有一个RouteDetailActivity.class,这是路线详情页面,然后通过Intent给它传递数据,type用于区分当前的出行类型,path用于显示详情信息,目前还没有这个Activity,所以你需要创建一个。
创建好之后,在刚才报错的地方导一下包就可以了。那么我们先不去写这个详情页面,先运行一下看看。
嗯,还是很不错的,那么下面来写这个详情页面,我还是比较注重这个外观的,希望能有一个好的用户体验,因此我打算美化一下这个详情页面,首先打开styles.xml,增加如下代码:
代码语言:txt复制 <!--详情页面主题-->
<style name="DetailTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#FFF</item>
<item name="colorPrimaryDark">#FFF</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
如下图所示:
你可以看到这里面还有一个主题AppTheme,下面进入到AndroidManifest.xml中,配置这个刚才创建的DetailTheme样式。
从这个图你可以看到很多有用的信息,首先是程序默认使用的是AppTheme主题,当你创建的Activity没有指定主题样式时,则都是AppTheme,大部分人后面都会修改主题样式,因为原生的太丑了,而我给RouteDetailActivity指定了DetailTheme主题,那么就会使用指定的主题。
下面进入activity_route_detail.xml页面,代码如下:
代码语言:txt复制<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#efefef"
android:fitsSystemWindows="true"
android:orientation="vertical">
<!--标题-->
<androidx.appcompat.widget.Toolbar
android:id="@ id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#FFF"
app:navigationIcon="@drawable/ic_black_24dp">
<TextView
android:id="@ id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textColor="#000"
android:textSize="16sp"
android:textStyle="bold" />
</androidx.appcompat.widget.Toolbar>
<!--分隔线-->
<View
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:background="#000" />
<!--路线详情-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@ id/tv_time"
android:layout_width="match_parent"
android:layout_height="70dp"
android:background="#FFF"
android:gravity="center_vertical"
android:orientation="vertical"
android:padding="5dp"
android:paddingStart="12dp"
android:textColor="#333333"
android:textSize="16sp" />
<ImageView
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#e0e0e0" />
<androidx.recyclerview.widget.RecyclerView
android:id="@ id/rv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:cacheColorHint="#00000000"
android:divider="#00000000"
android:fadingEdge="none"
android:fadingEdgeLength="0dp"
android:footerDividersEnabled="false"
android:headerDividersEnabled="false"
android:listSelector="#00000000"/>
</LinearLayout>
</LinearLayout>
下面进入到RouteDetailActivity,创建成员变量
代码语言:txt复制 private Toolbar toolbar;
private TextView tvTitle, tvTime;
private RecyclerView rv;//列表
然后新增一个initView方法,代码如下:
代码语言:txt复制 /**
* 初始化
*/
private void initView() {
toolbar = findViewById(R.id.toolbar);
tvTitle = findViewById(R.id.tv_title);
tvTime = findViewById(R.id.tv_time);
rv = findViewById(R.id.rv);
//高亮状态栏
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
}
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
Intent intent = getIntent();
if (intent == null) {
return;
}
switch (intent.getIntExtra("type", 0)) {
case 0://步行
break;
case 1://骑行
break;
case 2://驾车
break;
case 3://公交
break;
default:
break;
}
}
这里就是根绝传递进来的type做判断处理,下面就是显示详情数据了,这里我用的是RecyclerView,因此可以使用一个帮助框架。打开项目工程的build.gradle,添加如下库:
代码语言:txt复制 maven { url "https://jitpack.io" }
然后打开app下的build.gradle,在dependencies闭包里面添加如下依赖:
代码语言:txt复制 //RecyclerView的好搭档
implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.30'
然后点击右上角的Sync Now进行同步,下面创建列表的item布局,在layout下新建一个item_segment.xml文件,里面的代码如下:
代码语言:txt复制<?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="wrap_content"
android:background="#FFF" >
<ImageView
android:id="@ id/bus_seg_split_line"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginLeft="50dp"
android:layout_marginStart="50dp"
android:background="#e0e0e0"/>
<RelativeLayout
android:id="@ id/bus_route_direction"
android:layout_width="wrap_content"
android:layout_height="44dp"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginLeft="11dp"
android:layout_marginStart="11dp" >
<ImageView
android:id="@ id/bus_dir_icon"
android:layout_width="22dp"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:src="@drawable/dir_start" />
<ImageView
android:id="@ id/bus_dir_icon_up"
android:layout_width="2dp"
android:layout_height="match_parent"
android:layout_above="@id/bus_dir_icon"
android:layout_centerHorizontal="true"
android:background="#b6b6b6"
android:visibility="gone"/>
<ImageView
android:id="@ id/bus_dir_icon_down"
android:layout_width="2dp"
android:layout_height="match_parent"
android:layout_below="@id/bus_dir_icon"
android:layout_centerHorizontal="true"
android:background="#b6b6b6"
android:visibility="gone"/>
</RelativeLayout>
<RelativeLayout
android:id="@ id/bus_item"
android:layout_width="match_parent"
android:layout_height="44dp" >
<RelativeLayout
android:id="@ id/stationinfo"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_centerVertical="true"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true">
<ImageView
android:id="@ id/bus_expand_image"
android:layout_width="25dp"
android:layout_height="match_parent"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginEnd="6dp"
android:layout_marginRight="6dp"
android:clickable="true"
android:scaleType="centerInside"
android:src="@drawable/down"
android:visibility="gone" />
<TextView
android:id="@ id/bus_station_num"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_centerVertical="true"
android:layout_toLeftOf="@id/bus_expand_image"
android:layout_toStartOf="@id/bus_expand_image"
android:gravity="center_vertical"
android:textColor="#4c90f9"
android:textSize="12sp"
android:visibility="gone" >
</TextView>
</RelativeLayout>
<TextView
android:id="@ id/bus_line_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="50dp"
android:layout_marginStart="50dp"
android:layout_marginRight="70dp"
android:layout_marginEnd="70dp"
android:textColor="#333333"
android:text="出发"
android:textSize="14sp" />
</RelativeLayout>
<LinearLayout
android:id="@ id/expand_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/bus_item"
android:orientation="vertical">
</LinearLayout>
</RelativeLayout>
下面就来写列表适配器了,这里面会用到我刚才添加的那个依赖框架,它可以让你的RecycleView使用起来很简洁,在com.llw.mapdemo下新建一个adapter包,用于放置所有的适配器,在这个包下新建一个WalkSegmentListAdapter类,里面的代码如下:
代码语言:txt复制package com.llw.mapdemo.adapter;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.Nullable;
import com.amap.api.services.route.WalkStep;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.llw.mapdemo.R;
import com.llw.mapdemo.util.MapUtil;
import java.util.ArrayList;
import java.util.List;
/**
* 步行段列表适配器
*
* @author llw
* @date 2021/2/23 9:31
*/
public class WalkSegmentListAdapter extends BaseQuickAdapter<WalkStep, BaseViewHolder> {
private List<WalkStep> mItemList;
public WalkSegmentListAdapter(int layoutResId, @Nullable List<WalkStep> data) {
super(layoutResId, data);
mItemList = data;
}
@Override
protected void convert(BaseViewHolder helper, WalkStep item) {
TextView lineName = helper.getView(R.id.bus_line_name);
ImageView dirIcon = helper.getView(R.id.bus_dir_icon);
ImageView dirUp = helper.getView(R.id.bus_dir_icon_up);
ImageView dirDown = helper.getView(R.id.bus_dir_icon_down);
ImageView splitLine = helper.getView(R.id.bus_seg_split_line);
if (helper.getAdapterPosition() == 0) {
dirIcon.setImageResource(R.drawable.dir_start);
lineName.setText("出发");
dirUp.setVisibility(View.INVISIBLE);
dirDown.setVisibility(View.VISIBLE);
splitLine.setVisibility(View.INVISIBLE);
} else if (helper.getAdapterPosition() == mItemList.size() - 1) {
dirIcon.setImageResource(R.drawable.dir_end);
lineName.setText("到达终点");
dirUp.setVisibility(View.VISIBLE);
dirDown.setVisibility(View.INVISIBLE);
} else {
splitLine.setVisibility(View.VISIBLE);
dirUp.setVisibility(View.VISIBLE);
dirDown.setVisibility(View.VISIBLE);
String actionName = item.getAction();
int resID = MapUtil.getWalkActionID(actionName);
dirIcon.setImageResource(resID);
lineName.setText(item.getInstruction());
}
}
}
当你改完包名,放置了图标之后,你会发现有一个地方报错
这是因为还没有这个方法的,所以我们需要在MapUtil中添加这个方法。
代码语言:txt复制 public static int getWalkActionID(String actionName) {
if (actionName == null || actionName.equals("")) {
return R.drawable.dir13;
}
if ("左转".equals(actionName)) {
return R.drawable.dir2;
}
if ("右转".equals(actionName)) {
return R.drawable.dir1;
}
if ("向左前方".equals(actionName) || "靠左".equals(actionName) || actionName.contains("向左前方")) {
return R.drawable.dir6;
}
if ("向右前方".equals(actionName) || "靠右".equals(actionName) || actionName.contains("向右前方")) {
return R.drawable.dir5;
}
if ("向左后方".equals(actionName)|| actionName.contains("向左后方")) {
return R.drawable.dir7;
}
if ("向右后方".equals(actionName)|| actionName.contains("向右后方")) {
return R.drawable.dir8;
}
if ("直行".equals(actionName)) {
return R.drawable.dir3;
}
if ("通过人行横道".equals(actionName)) {
return R.drawable.dir9;
}
if ("通过过街天桥".equals(actionName)) {
return R.drawable.dir11;
}
if ("通过地下通道".equals(actionName)) {
return R.drawable.dir10;
}
return R.drawable.dir13;
}
就是通过你的行动ID来设置图标,很简单的方法。那么现在你的这个适配器就没有问题了,回到RouteDetailActivity。新写一个walkDetail方法
代码语言:txt复制 /**
* 步行详情
* @param intent
*/
private void walkDetail(Intent intent) {
tvTitle.setText("步行路线规划");
WalkPath walkPath = intent.getParcelableExtra("path");
String dur = MapUtil.getFriendlyTime((int) walkPath.getDuration());
String dis = MapUtil.getFriendlyLength((int) walkPath.getDistance());
tvTime.setText(dur "(" dis ")");
rv.setLayoutManager(new LinearLayoutManager(this));
rv.setAdapter(new WalkSegmentListAdapter(R.layout.item_segment, walkPath.getSteps()));
}
那么现在要做的就是方法的调用了,在步行中调用walkDetail方法。
当然还要在onCreate中调用initView();
下面运行一下: