This commit is contained in:
2026-03-26 16:58:57 +08:00
parent bf80931f37
commit b275c66383
7 changed files with 240 additions and 17 deletions

View File

@@ -7,6 +7,7 @@ import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.Typeface;
import android.graphics.drawable.GradientDrawable;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
@@ -23,6 +24,7 @@ import android.widget.Button;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
@@ -110,7 +112,11 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
private EditText endInput;
private LinearLayout searchArea; // 规划路线面板
private LinearLayout detailPanel; // 详情面板
private TextView tvStationName, tvStationAddr, tvRouteInfo;
private View modeMenu; //模式选择
private TextView tvStationName, tvStationAddr, planToggleBtn;
//时间 费用 里程 路费
private TextView tvDuration, tvDistance, tvTolls, tvTollsFuel;
private LatLng currentLatLng;
private String startName = "我的位置";
@@ -239,17 +245,57 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
bottomParams.setMargins(dp2px(12), 0, dp2px(12), dp2px(65));
container.addView(bottomContainer, bottomParams);
// --- 模式选择菜单 ---
modeMenu = createModeMenu(context);
modeMenu.setVisibility(View.GONE);
// 布局参数:位于规划按钮上方
FrameLayout.LayoutParams menuParams = new FrameLayout.LayoutParams(dp2px(130), ViewGroup.LayoutParams.WRAP_CONTENT);
menuParams.gravity = Gravity.BOTTOM | Gravity.END;
menuParams.setMargins(0, 0, dp2px(15), dp2px(330)); // 高度根据按钮位置调整
container.addView(modeMenu, menuParams);
// 加氢规划圆形按钮
planToggleBtn = new TextView(context);
planToggleBtn.setText("加氢\n规划");
planToggleBtn.setTextSize(11);
planToggleBtn.setTextColor(Color.WHITE);
planToggleBtn.setGravity(Gravity.CENTER);
planToggleBtn.setTypeface(Typeface.DEFAULT_BOLD);
// 设置深绿色圆形背景
planToggleBtn.setBackground(getCircleDrawable(Color.parseColor("#017143")));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
planToggleBtn.setElevation(dp2px(6));
}
planToggleBtn.setOnClickListener(v -> {
// 切换菜单显示/隐藏
modeMenu.setVisibility(modeMenu.getVisibility() == View.VISIBLE ? View.GONE : View.VISIBLE);
});
int layoutSize = dp2px(44);
FrameLayout.LayoutParams toggleParams = new FrameLayout.LayoutParams(layoutSize, layoutSize);
toggleParams.gravity = Gravity.BOTTOM | Gravity.END;
toggleParams.setMargins(0, 0, dp2px(12), dp2px(340)); // 位于定位按钮上方
container.addView(planToggleBtn, toggleParams);
// --- 右下角定位按钮 ---
ImageButton locBtn = new ImageButton(context);
locBtn.setImageResource(android.R.drawable.ic_menu_mylocation);
locBtn.setBackground(getRoundedDrawable(Color.WHITE, 25));
locBtn.setElevation(dp2px(4));
locBtn.setImageResource(R.drawable.ic_location);
// 设置自定义的白色圆形背景
locBtn.setBackgroundColor(Color.TRANSPARENT);
// 设置投影(仅在 API 21+ 有效,能产生干净的阴影而非黑块)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
locBtn.setElevation(dp2px(4));
}
locBtn.setScaleType(ImageView.ScaleType.FIT_CENTER);
int padding = dp2px(2);
locBtn.setPadding(padding, padding, padding, padding);
locBtn.setOnClickListener(v -> {
if (currentLatLng != null)
aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(currentLatLng, 15f));
});
FrameLayout.LayoutParams locParams = new FrameLayout.LayoutParams(dp2px(44), dp2px(44));
locParams.setMargins(0, 0, dp2px(15), dp2px(250)); // 调高一点,避开底部的面板
FrameLayout.LayoutParams locParams = new FrameLayout.LayoutParams(layoutSize, layoutSize);
locParams.setMargins(0, 0, dp2px(15), dp2px(285)); // 调高一点,避开底部的面板
locParams.gravity = Gravity.BOTTOM | Gravity.END;
container.addView(locBtn, locParams);
}
@@ -259,24 +305,71 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
panel.setOrientation(LinearLayout.VERTICAL);
panel.setBackground(getRoundedDrawable(Color.WHITE, 16));
panel.setPadding(dp2px(20), dp2px(20), dp2px(20), dp2px(20));
panel.setElevation(dp2px(12));
// --- (包含标题和关闭按钮) ---
LinearLayout titleLayout = new LinearLayout(context);
titleLayout.setOrientation(LinearLayout.HORIZONTAL);
titleLayout.setGravity(Gravity.CENTER_VERTICAL);
// 站点名称 (设置 weight: 1 占据剩余空间)
tvStationName = new TextView(context);
tvStationName.setTextSize(18);
tvStationName.setTextColor(Color.BLACK);
tvStationName.setTypeface(Typeface.DEFAULT_BOLD);
panel.addView(tvStationName);
LinearLayout.LayoutParams nameParams = new LinearLayout.LayoutParams(
0, ViewGroup.LayoutParams.WRAP_CONTENT, 1.0f);
titleLayout.addView(tvStationName, nameParams);
// 关闭按钮 (X)
ImageView ivClose = new ImageView(context);
ivClose.setImageResource(R.drawable.ic_close);
ivClose.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
ivClose.setPadding(dp2px(5), dp2px(5), dp2px(5), dp2px(5));
ivClose.setOnClickListener(v -> {
if (detailPanel != null)
detailPanel.setVisibility(View.GONE);
searchArea.setVisibility(View.VISIBLE);
planToggleBtn.setVisibility(View.VISIBLE);
});
LinearLayout.LayoutParams closeParams = new LinearLayout.LayoutParams(dp2px(28), dp2px(28));
titleLayout.addView(ivClose, closeParams);
panel.addView(titleLayout);
tvStationAddr = new TextView(context);
tvStationAddr.setTextSize(13);
tvStationAddr.setPadding(0, dp2px(4), 0, dp2px(10));
tvStationAddr.setPadding(0, dp2px(4), 0, 0);
tvStationAddr.setTextColor(Color.GRAY);
panel.addView(tvStationAddr);
tvRouteInfo = new TextView(context);
tvRouteInfo.setTextSize(14);
tvRouteInfo.setTextColor(Color.parseColor("#333333"));
panel.addView(tvRouteInfo);
/*内容*/
LinearLayout routeInfoLayout = new LinearLayout(context);
routeInfoLayout.setOrientation(LinearLayout.VERTICAL);
routeInfoLayout.setPadding(0, dp2px(5), 0, 0);
// 第一行:预计时间
LinearLayout row1 = new LinearLayout(context);
row1.setOrientation(LinearLayout.HORIZONTAL);
row1.setGravity(Gravity.CENTER_VERTICAL);
row1.setPadding(0, dp2px(8), 0, 0); // 增加行间距
tvDuration = createInfoItem(row1, R.drawable.ic_time, "预计时间:", "", 1.0f);
tvTollsFuel = createInfoItem(row1, R.drawable.ic_fuel, "加氢费用:", "", 1.0f);
routeInfoLayout.addView(row1);
// 第二行:里程 + 过路费
LinearLayout row2 = new LinearLayout(context);
row2.setOrientation(LinearLayout.HORIZONTAL);
row2.setGravity(Gravity.CENTER_VERTICAL);
row2.setPadding(0, dp2px(10), 0, 0); // 增加行间距
// 里程
tvDistance = createInfoItem(row2, R.drawable.ic_mileage, "行驶里程:", "", 1.0f);
// 过路费
tvTolls = createInfoItem(row2, R.drawable.ic_toll, "过路费:", "", 1.0f);
routeInfoLayout.addView(row2);
panel.addView(routeInfoLayout);
Button startNaviBtn = new Button(context);
startNaviBtn.setText("开始导航");
@@ -328,14 +421,24 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
if (rCode == AMapException.CODE_AMAP_SUCCESS && result != null && !result.getPaths().isEmpty()) {
DrivePath path = result.getPaths().get(0);
// 规划成功,显示详情面板
// 规划成功,显示详情面板,隐藏模式选择
detailPanel.setVisibility(View.VISIBLE);
planToggleBtn.setVisibility(View.GONE);
modeMenu.setVisibility(View.GONE);
tvStationName.setText(endName);
tvStationAddr.setText(endAddress);
String info = String.format("预计时间:%d分钟 | 行驶里程:%.1f公里 | 预计路费:%.0f元",
path.getDuration() / 60, path.getDistance() / 1000f, path.getTolls());
tvRouteInfo.setText(info);
double distanceKm = path.getDistance() / 1000f;
long durationMin = path.getDuration() / 60;
double tolls = path.getTolls();
String hydrogenCost = truckRouteData.algorithmPath.hydrogenCost;
tvDuration.setText("预计时间:" + durationMin + "分钟");
tvDistance.setText("行驶里程:" + String.format("%.1f", distanceKm) + "公里");
tvTolls.setText("过路费:" + (int) tolls + "");
tvTollsFuel.setText("加氢费用:" + hydrogenCost + "");
aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(endPoint, 13f));
} else {
@@ -806,6 +909,126 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
mapView.onDestroy();
}
/**
* 辅助方法:创建带图标的文本项
*/
private TextView createInfoItem(LinearLayout parent, int iconRes, String label, String value, float weight) {
LinearLayout itemContainer = new LinearLayout(mContext);
itemContainer.setOrientation(LinearLayout.HORIZONTAL);
itemContainer.setGravity(Gravity.CENTER_VERTICAL);
// 图标
ImageView iv = new ImageView(mContext);
iv.setImageResource(iconRes);
iv.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
iv.setColorFilter(Color.parseColor("#017143")); // 统一设为主题绿
itemContainer.addView(iv, new LinearLayout.LayoutParams(dp2px(18), dp2px(18)));
// 文本内容
TextView tv = new TextView(mContext);
tv.setText(label + value);
tv.setTextSize(14);
tv.setTextColor(Color.parseColor("#333333"));
tv.setPadding(dp2px(6), 0, 0, 0);
LinearLayout.LayoutParams tvParams = new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 1.0f);
itemContainer.addView(tv, tvParams);
// 将整个项加入父容器
LinearLayout.LayoutParams containerParams = new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, weight);
parent.addView(itemContainer, containerParams);
return tv; // 返回TextView以便后续更新内容
}
// 过载一个不需要weight的方法给第一行使用
private TextView createInfoItem(LinearLayout parent, int iconRes, String label, String value) {
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
ImageView iv = new ImageView(mContext);
iv.setImageResource(iconRes);
iv.setColorFilter(Color.parseColor("#017143"));
parent.addView(iv, new LinearLayout.LayoutParams(dp2px(18), dp2px(18)));
TextView tv = new TextView(mContext);
tv.setTextSize(14);
tv.setTextColor(Color.parseColor("#333333"));
tv.setPadding(dp2px(6), 0, 0, 0);
parent.addView(tv, params);
return tv;
}
// 创建模式菜单视图
private View createModeMenu(Context context) {
LinearLayout menu = new LinearLayout(context);
menu.setOrientation(LinearLayout.VERTICAL);
menu.setBackground(getRoundedDrawable(Color.WHITE, 12));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
menu.setElevation(dp2px(10));
}
// 1. 成本计算模式 (高亮绿色头部)
TextView item1 = createMenuItem(context, "成本计算模式", true);
item1.setOnClickListener(v -> switchMode("成本计算"));
// 2. 送货规划模式
TextView item2 = createMenuItem(context, "送货规划模式", false);
item2.setOnClickListener(v -> switchMode("送货规划"));
// 3. 加氢规划模式
TextView item3 = createMenuItem(context, "加氢规划模式", false);
item3.setOnClickListener(v -> switchMode("加氢规划"));
menu.addView(item1);
menu.addView(item2);
menu.addView(item3);
return menu;
}
private TextView createMenuItem(Context context, String text, boolean isHighlight) {
TextView tv = new TextView(context);
tv.setText(text);
tv.setTextSize(13);
tv.setPadding(dp2px(15), dp2px(12), dp2px(15), dp2px(12));
tv.setGravity(Gravity.CENTER);
if (isHighlight) {
tv.setTextColor(Color.WHITE);
// 顶部圆角绿色背景
tv.setBackground(getTopRoundedDrawable(Color.parseColor("#27AE60"), 12));
} else {
tv.setTextColor(Color.parseColor("#666666"));
tv.setBackgroundColor(Color.TRANSPARENT);
}
return tv;
}
private void switchMode(String mode) {
// 处理模式切换逻辑
Toast.makeText(mContext, "切换到:" + mode, Toast.LENGTH_SHORT).show();
modeMenu.setVisibility(View.GONE);
}
// 获取纯圆形背景
private GradientDrawable getCircleDrawable(int color) {
GradientDrawable gd = new GradientDrawable();
gd.setColor(color);
gd.setShape(GradientDrawable.OVAL);
return gd;
}
// 获取顶部带圆角,底部直角的背景(用于菜单第一项)
private GradientDrawable getTopRoundedDrawable(int color, int radiusDp) {
float r = dp2px(radiusDp);
GradientDrawable gd = new GradientDrawable();
gd.setColor(color);
// 顺序左上x2, 右上x2, 右下x2, 左下x2
gd.setCornerRadii(new float[]{r, r, r, r, 0, 0, 0, 0});
return gd;
}
/**
* 解析接口返回的data数据
*/

Binary file not shown.

After

Width:  |  Height:  |  Size: 880 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 810 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 924 B