20 Commits

Author SHA1 Message Date
0a2c7683b7 更新配置 2026-04-20 09:23:36 +08:00
8e79d8039c fix 2026-04-16 13:43:11 +08:00
2523899ec4 路径更换线上 2026-04-16 11:29:51 +08:00
853a9135c8 线上配置 2026-04-16 11:10:35 +08:00
ec96a96be2 Merge branch 'dev_map' into dev
version 1.2.5
# Conflicts:
#	ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Class/ASearchAddressController.m
#	ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/View/AStationDetailPopupView.m
2026-04-16 10:50:57 +08:00
xiaogg
0ba9547992 fix:优化完善; 2026-04-15 20:03:37 +08:00
c6e7616be2 fix 2026-04-15 10:06:58 +08:00
eae654c47e fix 2026-04-14 14:04:19 +08:00
f01875abb9 调整 2026-04-14 11:50:33 +08:00
881da166d1 调整 2026-04-13 17:48:37 +08:00
14b2e6b35c Merge branch 'dev_map' into dev 2026-04-13 16:54:07 +08:00
20c39a4a12 样式调整 2026-04-13 16:38:46 +08:00
xiaogg
5c74c7ccc0 fix:优化完善; 2026-04-13 16:13:23 +08:00
23fc0da5c8 新增字段 2026-04-13 15:05:29 +08:00
7efd933416 新增字段 2026-04-09 14:05:27 +08:00
2b33dac384 语音 2026-04-08 10:59:43 +08:00
ef60b8ed62 Merge branch 'map_dev' into dev 2026-04-03 10:25:53 +08:00
bec6952707 Merge branch 'dev_map' into map_dev 2026-04-02 09:11:14 +08:00
f68349a208 Merge branch 'dev_map' into dev 2026-04-01 17:38:48 +08:00
xiaogg
08dcc64ef4 fix:优化完善; 2026-04-01 15:12:54 +08:00
58 changed files with 2702 additions and 410 deletions

View File

@@ -0,0 +1,7 @@
{
"permissions": {
"allow": [
"Bash(./gradlew assembleDebug --stacktrace)"
]
}
}

View File

@@ -37,8 +37,8 @@ android {
// For more information, see: https://flutter.dev/to/review-gradle-config. // For more information, see: https://flutter.dev/to/review-gradle-config.
minSdk = flutter.minSdkVersion minSdk = flutter.minSdkVersion
targetSdk = flutter.targetSdkVersion targetSdk = flutter.targetSdkVersion
versionCode = 7 versionCode = 8
versionName = "1.2.4" versionName = "1.2.5"
} }
signingConfigs { signingConfigs {
@@ -72,4 +72,5 @@ flutter {
dependencies { dependencies {
implementation("com.amap.api:navi-3dmap-location-search:10.0.700_3dmap10.0.700_loc6.4.5_sea9.7.2") implementation("com.amap.api:navi-3dmap-location-search:10.0.700_3dmap10.0.700_loc6.4.5_sea9.7.2")
implementation("com.squareup.okhttp3:okhttp:4.12.0") implementation("com.squareup.okhttp3:okhttp:4.12.0")
implementation("androidx.appcompat:appcompat:1.7.1")
} }

View File

@@ -50,6 +50,13 @@
android:theme="@android:style/Theme.NoTitleBar" android:theme="@android:style/Theme.NoTitleBar"
android:configChanges="orientation|keyboardHidden|screenSize|navigation" android:configChanges="orientation|keyboardHidden|screenSize|navigation"
android:screenOrientation="portrait" /> android:screenOrientation="portrait" />
<!--搜索目的地 Activity-->
<activity
android:name="com.lnkj.ln_jq_app.SearchDestinationActivity"
android:theme="@android:style/Theme.NoTitleBar"
android:configChanges="orientation|keyboardHidden|screenSize|navigation"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustResize" />
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"

View File

@@ -1,6 +1,7 @@
package com.lnkj.ln_jq_app; package com.lnkj.ln_jq_app;
import android.Manifest; import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.os.Build; import android.os.Build;
import android.util.Log; import android.util.Log;
@@ -37,6 +38,9 @@ public class MainActivity extends FlutterActivity {
"NativeFirstPage", "NativeFirstPage",
new NativeMapFactory(this) new NativeMapFactory(this)
); );
// 设置 Activity 实例到地图
NativeMapFactory.setActivity(this);
} }
/** /**
@@ -73,9 +77,9 @@ public class MainActivity extends FlutterActivity {
if (!deniedPermissions.isEmpty()) { if (!deniedPermissions.isEmpty()) {
ActivityCompat.requestPermissions( ActivityCompat.requestPermissions(
this, this,
deniedPermissions.toArray(new String[0]), deniedPermissions.toArray(new String[0]),
PERMISSION_REQUEST_CODE PERMISSION_REQUEST_CODE
); );
} else { } else {
Log.d(TAG, "所有必要权限已授予"); Log.d(TAG, "所有必要权限已授予");
@@ -108,6 +112,27 @@ public class MainActivity extends FlutterActivity {
} }
} }
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// 处理从搜索目的地页面返回的结果
if (requestCode == 1000 && resultCode == RESULT_OK && data != null) {
String name = data.getStringExtra(SearchDestinationActivity.EXTRA_RESULT_NAME);
String address = data.getStringExtra(SearchDestinationActivity.EXTRA_RESULT_ADDRESS);
double lat = data.getDoubleExtra(SearchDestinationActivity.EXTRA_RESULT_LAT, 0);
double lon = data.getDoubleExtra(SearchDestinationActivity.EXTRA_RESULT_LON, 0);
String district = data.getStringExtra(SearchDestinationActivity.EXTRA_RESULT_DISTRICT);
if (name != null && lat != 0 && lon != 0) {
// 获取地图实例并设置目的地
NativeMapView mapView = NativeMapFactory.getMapView();
if (mapView != null) {
mapView.setDestination(name, address, lat, lon, district);
}
}
}
}
@Override @Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {

View File

@@ -1,5 +1,6 @@
package com.lnkj.ln_jq_app; package com.lnkj.ln_jq_app;
import android.app.Activity;
import android.content.Context; import android.content.Context;
import io.flutter.plugin.common.MessageCodec; import io.flutter.plugin.common.MessageCodec;
@@ -34,4 +35,13 @@ public class NativeMapFactory extends PlatformViewFactory {
public static NativeMapView getMapView() { public static NativeMapView getMapView() {
return mapViewInstance; return mapViewInstance;
} }
/**
* 设置 Activity 实例
*/
public static void setActivity(Activity activity) {
if (mapViewInstance != null) {
mapViewInstance.setActivity(activity);
}
}
} }

View File

@@ -8,34 +8,23 @@ import android.graphics.BitmapFactory;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.PorterDuff; import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.GradientDrawable; import android.graphics.drawable.GradientDrawable;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.text.Editable;
import android.text.InputType;
import android.text.TextUtils; import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log; import android.util.Log;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.Gravity; import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.ArrayAdapter;
import android.widget.Button; import android.widget.Button;
import android.widget.EditText;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import android.widget.ImageButton; import android.widget.ImageButton;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
@@ -71,11 +60,7 @@ import com.amap.api.services.geocoder.GeocodeSearch;
import com.amap.api.services.geocoder.RegeocodeAddress; import com.amap.api.services.geocoder.RegeocodeAddress;
import com.amap.api.services.geocoder.RegeocodeQuery; import com.amap.api.services.geocoder.RegeocodeQuery;
import com.amap.api.services.geocoder.RegeocodeResult; import com.amap.api.services.geocoder.RegeocodeResult;
import com.amap.api.services.help.Inputtips;
import com.amap.api.services.help.InputtipsQuery;
import com.amap.api.services.help.Tip;
import com.amap.api.services.route.BusRouteResult; import com.amap.api.services.route.BusRouteResult;
import com.amap.api.services.route.DrivePath;
import com.amap.api.services.route.DriveRouteResult; import com.amap.api.services.route.DriveRouteResult;
import com.amap.api.services.route.RideRouteResult; import com.amap.api.services.route.RideRouteResult;
import com.amap.api.services.route.RouteSearch; import com.amap.api.services.route.RouteSearch;
@@ -91,7 +76,6 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import io.flutter.plugin.platform.PlatformView; import io.flutter.plugin.platform.PlatformView;
import okhttp3.Call; import okhttp3.Call;
import okhttp3.Callback; import okhttp3.Callback;
@@ -104,7 +88,7 @@ import okhttp3.Response;
/** /**
* 高德地图导航 * 高德地图导航
*/ */
public class NativeMapView implements PlatformView, LocationSource, AMapLocationListener, GeocodeSearch.OnGeocodeSearchListener, RouteSearch.OnRouteSearchListener, AMap.OnMarkerClickListener, Inputtips.InputtipsListener { public class NativeMapView implements PlatformView, LocationSource, AMapLocationListener, GeocodeSearch.OnGeocodeSearchListener, RouteSearch.OnRouteSearchListener, AMap.OnMarkerClickListener {
private static final String TAG = "NativeMapView"; private static final String TAG = "NativeMapView";
private final FrameLayout container; private final FrameLayout container;
@@ -120,17 +104,14 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
private final OkHttpClient httpClient = new OkHttpClient(); private final OkHttpClient httpClient = new OkHttpClient();
// UI组件 // UI组件
private EditText endInput; private TextView endInput;
private LinearLayout searchArea; // 规划路线面板 private LinearLayout searchArea; // 规划路线面板
private LinearLayout detailPanel; // 详情面板 private LinearLayout detailPanel; // 详情面板
private View modeMenu; //模式选择 private View modeMenu; //模式选择
private TextView tvStationName, tvStationAddr, planToggleBtn; private TextView tvStationName, tvStationAddr, planToggleBtn, tvBusinessHours;
private ListView suggestionList; // 输入提示列表
private ArrayAdapter<String> suggestionAdapter; // 提示列表适配器
private List<Tip> currentTipList; // 当前提示列表
//时间 费用 里程 路费 //时间 费用 里程 路费
private TextView tvDuration, tvDistance, tvTolls, tvTollsFuel; private TextView tvDuration, tvDistance, tvTolls, tvTollsFuel, tvPerson, tvPrice, tvPhone;
private LatLng currentLatLng; private LatLng currentLatLng;
private String startName = "我的位置"; private String startName = "我的位置";
@@ -140,28 +121,32 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
private LatLng endPoint; private LatLng endPoint;
private boolean isFirstLocation = true; private boolean isFirstLocation = true;
private boolean isUserSelectedDestination = false; // 标识用户是否手动选择了目的地 private boolean isUserSelectedDestination = false; // 标识用户是否手动选择了目的地
private boolean isProgrammaticTextChange = false; // 标识是否是程序自动设置文本
private final List<Marker> stationMarkers = new ArrayList<>(); private final List<Marker> stationMarkers = new ArrayList<>();
// 存储token和车牌号 // 存储token和车牌号
private String token; private String token;
private String plateNumber; private String plateNumber;
private String mDebugUrl = "https://beta-esg.api.lnh2e.com/appointment/"; // private String mDebugUrl = "https://beta-esg.api.lnh2e.com/appointment/";
private String mReleaseUrl = ""; //线上环境
private String mDebugUrl = "http://47.101.201.13:8443/api/appointment/";
// 存储货车路线算法接口返回的数据 // 存储货车路线算法接口返回的数据
private TruckRouteData truckRouteData; private TruckRouteData truckRouteData;
//当前定位信息 //当前定位信息
private AMapLocation mLoc; private AMapLocation mLoc;
private ImageButton mLocBtn;
public NativeMapView(Context context, int id, Object args) { public NativeMapView(Context context, int id, Object args) {
this.mContext = context; this.mContext = context;
mActivity = getActivityFromContext(context); mActivity = getActivityFromContext(context);
MapsInitializer.updatePrivacyShow(mActivity, true, true); // 确保 mActivity 不为 null如果为 null 则使用 context
MapsInitializer.updatePrivacyAgree(mActivity, true); Activity activity = mActivity != null ? mActivity : (context instanceof Activity ? (Activity) context : null);
MapsInitializer.updatePrivacyShow(activity, true, true);
MapsInitializer.updatePrivacyAgree(activity, true);
mapView = new MapView(context); mapView = new MapView(context);
mapView.onCreate(null); mapView.onCreate(null);
@@ -203,7 +188,7 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
bottomContainer = new LinearLayout(context); bottomContainer = new LinearLayout(context);
bottomContainer.setOrientation(LinearLayout.VERTICAL); bottomContainer.setOrientation(LinearLayout.VERTICAL);
bottomContainer.setGravity(Gravity.BOTTOM); bottomContainer.setGravity(Gravity.BOTTOM);
bottomContainer.setBackgroundResource(R.drawable.rounded_top_bg);
// 1. 详情面板 (用于显示加氢站详细信息,初始隐藏) // 1. 详情面板 (用于显示加氢站详细信息,初始隐藏)
detailPanel = createDetailPanel(context); detailPanel = createDetailPanel(context);
detailPanel.setVisibility(View.GONE); detailPanel.setVisibility(View.GONE);
@@ -218,141 +203,89 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
searchArea.setFocusable(true); searchArea.setFocusable(true);
searchArea.setFocusableInTouchMode(true); searchArea.setFocusableInTouchMode(true);
endInput = new EditText(context); endInput = new TextView(context);
endInput.setHint("请输入目的地,不输入则自动匹配推荐加氢站"); endInput.setHint("请输入目的地,不输入则自动匹配推荐加氢站");
endInput.setTextSize(13); endInput.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_search, 0, 0, 0);
endInput.setCompoundDrawablePadding(dp2px(8));
endInput.setTextSize(12);
endInput.setTextColor(Color.parseColor("#333333"));
endInput.setHintTextColor(Color.GRAY); endInput.setHintTextColor(Color.GRAY);
endInput.setPadding(dp2px(12), dp2px(12), dp2px(12), dp2px(12)); endInput.setPadding(dp2px(12), dp2px(12), dp2px(12), dp2px(12));
endInput.setBackground(getRoundedDrawable(Color.parseColor("#F8F8F8"), 8)); endInput.setBackground(getRoundedDrawable(Color.parseColor("#F8F8F8"), 8));
endInput.setSingleLine(true); endInput.setSingleLine(true);
endInput.setInputType(InputType.TYPE_CLASS_TEXT); // 明确输入类型 endInput.setGravity(Gravity.CENTER_VERTICAL);
endInput.setImeOptions(EditorInfo.IME_ACTION_SEARCH); endInput.setOnClickListener(v -> {
endInput.setFocusable(true); try {
endInput.setFocusableInTouchMode(true); Log.d(TAG, "endInput clicked, mActivity=" + (mActivity != null ? "not null" : "null"));
endInput.setClickable(true);
endInput.setCursorVisible(true);
// 针对 EditText 的特殊处理 // 设置回调
endInput.setOnTouchListener((v, event) -> { SearchDestinationActivity.setCallback((name, address, lat, lon, district) -> {
if (event.getAction() == MotionEvent.ACTION_UP) { Log.d(TAG, "Callback received: " + name + ", lat=" + lat + ", lon=" + lon);
v.requestFocus(); // 直接设置,不依赖 mActivity.runOnUiThread
v.postDelayed(() -> { setDestination(name, address, lat, lon, district);
InputMethodManager imm = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE); });
if (imm != null) {
// 使用 SHOW_FORCED 或确保结果成功 // 跳转到搜索目的地页面 - 使用更安全的方式
imm.showSoftInput(v, InputMethodManager.SHOW_FORCED); Intent intent = new Intent(mContext, SearchDestinationActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Log.d(TAG, "Starting SearchDestinationActivity with intent");
mContext.startActivity(intent);
} catch (Exception e) {
Log.e(TAG, "Failed to start SearchDestinationActivity", e);
e.printStackTrace();
// 显示错误提示
try {
if (mContext != null) {
Toast.makeText(mContext, "无法打开搜索页面: " + e.getMessage(), Toast.LENGTH_SHORT).show();
} }
}, 100); } catch (Exception toastException) {
} Log.e(TAG, "Failed to show toast", toastException);
return false;
});
// 处理搜索键按下
endInput.setOnEditorActionListener((v, actionId, event) -> {
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
suggestionList.setVisibility(View.GONE);
// 可以在这里直接触发路线规划,但保持原来的按钮点击逻辑
return true;
}
return false;
});
// 初始化提示列表
currentTipList = new ArrayList<>();
suggestionList = new ListView(context);
suggestionList.setBackgroundColor(Color.WHITE);
suggestionList.setDividerHeight(1);
suggestionList.setDivider(new ColorDrawable(Color.LTGRAY));
suggestionList.setPadding(dp2px(5), dp2px(5), dp2px(5), dp2px(5));
suggestionAdapter = new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1, new ArrayList<>()) {
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
// 获取默认的 View
View view = super.getView(position, convertView, parent);
TextView text = view.findViewById(android.R.id.text1);
text.setTextColor(Color.parseColor("#333333"));
text.setTextSize(14);
view.setBackgroundColor(Color.TRANSPARENT);
return view;
}
};
suggestionList.setAdapter(suggestionAdapter);
suggestionList.setVisibility(View.GONE);
suggestionList.setOnItemClickListener((parent, view, position, id) -> {
Tip tip = currentTipList.get(position);
if (tip.getPoint() != null) {
endPoint = new LatLng(tip.getPoint().getLatitude(), tip.getPoint().getLongitude());
String name = tip.getName();
String district = tip.getDistrict();
endName = name;
endAddress = tip.getAddress();
isGetInputtips = true;
isUserSelectedDestination = true; // 标识用户手动选择了目的地
isProgrammaticTextChange = true; // 标识是程序自动设置文本
endInput.setText(district != null && !district.isEmpty() ? name + " " + district : name);
isProgrammaticTextChange = false; // 恢复标志
suggestionList.setVisibility(View.GONE);
}
});
endInput.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// 如果是程序自动设置文本,不触发搜索
if (isProgrammaticTextChange) {
return;
} }
if (s.length() > 1) {
// 使用当前位置的城市进行搜索
String city = currentLatLng != null ? "" : "";
InputtipsQuery query = new InputtipsQuery(s.toString(), "");
query.setCityLimit(false);
Inputtips inputtips = new Inputtips(mContext, query);
inputtips.setInputtipsListener(NativeMapView.this);
inputtips.requestInputtipsAsyn();
} else {
suggestionList.setVisibility(View.GONE);
}
}
@Override
public void afterTextChanged(Editable s) {
}
});
endInput.setOnFocusChangeListener((v, hasFocus) -> {
if (!hasFocus) {
suggestionList.setVisibility(View.GONE);
} }
}); });
searchArea.addView(endInput); searchArea.addView(endInput);
searchArea.addView(suggestionList);
View vSpace = new View(context); View vSpace = new View(context);
searchArea.addView(vSpace, new LinearLayout.LayoutParams(1, dp2px(12))); searchArea.addView(vSpace, new LinearLayout.LayoutParams(1, dp2px(12)));
Button planBtn = new Button(context); // 创建自定义按钮布局
planBtn.setText("规划路线"); LinearLayout planBtnContainer = new LinearLayout(context);
planBtn.setTextColor(Color.WHITE); planBtnContainer.setOrientation(LinearLayout.HORIZONTAL);
planBtn.setTypeface(Typeface.DEFAULT_BOLD); planBtnContainer.setGravity(Gravity.CENTER);
planBtn.setBackground(getRoundedDrawable(Color.parseColor("#017143"), 99)); planBtnContainer.setBackground(getRoundedDrawable(Color.parseColor("#017143"), 99));
planBtn.setOnClickListener(v -> calculateRouteBeforeNavi()); planBtnContainer.setPadding(0, 0, 0, 0);
searchArea.addView(planBtn, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, dp2px(48)));
// 添加图标
ImageView pathIcon = new ImageView(context);
pathIcon.setImageResource(R.drawable.ic_path);
pathIcon.setColorFilter(Color.WHITE);
LinearLayout.LayoutParams iconParams = new LinearLayout.LayoutParams(dp2px(20), dp2px(20));
iconParams.rightMargin = dp2px(6); // 图标和文字之间的间距
planBtnContainer.addView(pathIcon, iconParams);
// 添加文字
TextView planText = new TextView(context);
planText.setText("规划路线");
planText.setTextColor(Color.WHITE);
planText.setTextSize(14);
planText.setTypeface(Typeface.DEFAULT_BOLD);
planText.setGravity(Gravity.CENTER);
planBtnContainer.addView(planText);
// 设置点击事件
planBtnContainer.setOnClickListener(v -> calculateRouteBeforeNavi());
searchArea.addView(planBtnContainer, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, dp2px(40)));
bottomContainer.addView(searchArea); bottomContainer.addView(searchArea);
// 设置统一的底部间距 // 设置统一的底部间距
FrameLayout.LayoutParams bottomParams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); FrameLayout.LayoutParams bottomParams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
bottomParams.gravity = Gravity.BOTTOM; bottomParams.gravity = Gravity.BOTTOM;
bottomParams.setMargins(dp2px(12), 0, dp2px(12), dp2px(65));
container.addView(bottomContainer, bottomParams); container.addView(bottomContainer, bottomParams);
container.setPadding(0, 0, 0, dp2px(65));
// --- 模式选择菜单 --- // --- 模式选择菜单 ---
@@ -361,9 +294,10 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
// 布局参数:位于规划按钮上方 // 布局参数:位于规划按钮上方
FrameLayout.LayoutParams menuParams = new FrameLayout.LayoutParams(dp2px(130), ViewGroup.LayoutParams.WRAP_CONTENT); FrameLayout.LayoutParams menuParams = new FrameLayout.LayoutParams(dp2px(130), ViewGroup.LayoutParams.WRAP_CONTENT);
menuParams.gravity = Gravity.BOTTOM | Gravity.END; menuParams.gravity = Gravity.BOTTOM | Gravity.END;
menuParams.setMargins(0, 0, dp2px(15), dp2px(330)); // 高度根据按钮位置调整 menuParams.setMargins(0, 0, dp2px(15), dp2px(230)); // 高度根据按钮位置调整
container.addView(modeMenu, menuParams); container.addView(modeMenu, menuParams);
// 加氢规划圆形按钮 // 加氢规划圆形按钮
planToggleBtn = new TextView(context); planToggleBtn = new TextView(context);
planToggleBtn.setText("加氢\n规划"); planToggleBtn.setText("加氢\n规划");
@@ -384,71 +318,37 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
int layoutSize = dp2px(44); int layoutSize = dp2px(44);
FrameLayout.LayoutParams toggleParams = new FrameLayout.LayoutParams(layoutSize, layoutSize); FrameLayout.LayoutParams toggleParams = new FrameLayout.LayoutParams(layoutSize, layoutSize);
toggleParams.gravity = Gravity.BOTTOM | Gravity.END; toggleParams.gravity = Gravity.BOTTOM | Gravity.END;
toggleParams.setMargins(0, 0, dp2px(12), dp2px(340)); // 位于定位按钮上方 toggleParams.setMargins(0, 0, dp2px(12), dp2px(210)); // 位于定位按钮上方
container.addView(planToggleBtn, toggleParams); container.addView(planToggleBtn, toggleParams);
// --- 右下角定位按钮 --- // --- 右下角定位按钮 ---
ImageButton locBtn = new ImageButton(context); mLocBtn = new ImageButton(context);
locBtn.setImageResource(R.drawable.ic_location); mLocBtn.setImageResource(R.drawable.ic_location);
// 设置自定义的白色圆形背景 // 设置自定义的白色圆形背景
locBtn.setBackgroundColor(Color.TRANSPARENT); mLocBtn.setBackgroundColor(Color.TRANSPARENT);
// 设置投影(仅在 API 21+ 有效,能产生干净的阴影而非黑块) // 设置投影(仅在 API 21+ 有效,能产生干净的阴影而非黑块)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
locBtn.setElevation(dp2px(4)); mLocBtn.setElevation(dp2px(4));
} }
locBtn.setScaleType(ImageView.ScaleType.FIT_CENTER); mLocBtn.setScaleType(ImageView.ScaleType.FIT_CENTER);
int padding = dp2px(2); int padding = dp2px(2);
locBtn.setPadding(padding, padding, padding, padding); mLocBtn.setPadding(padding, padding, padding, padding);
locBtn.setOnClickListener(v -> { mLocBtn.setOnClickListener(v -> {
if (currentLatLng != null) if (currentLatLng != null)
aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(currentLatLng, 15f)); aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(currentLatLng, 15f));
}); });
FrameLayout.LayoutParams locParams = new FrameLayout.LayoutParams(layoutSize, layoutSize); FrameLayout.LayoutParams locParams = new FrameLayout.LayoutParams(layoutSize, layoutSize);
locParams.setMargins(0, 0, dp2px(15), dp2px(285)); // 调高一点,避开底部的面板 locParams.setMargins(0, 0, dp2px(15), dp2px(150)); // 调高一点,避开底部的面板
locParams.gravity = Gravity.BOTTOM | Gravity.END; locParams.gravity = Gravity.BOTTOM | Gravity.END;
container.addView(locBtn, locParams); container.addView(mLocBtn, locParams);
//最后调用监听函数
addKeyboardListener();
} }
private void addKeyboardListener() {
container.getViewTreeObserver().addOnGlobalLayoutListener(() -> {
Rect r = new Rect();
// 获取当前窗口可视区域
container.getWindowVisibleDisplayFrame(r);
// screenHeight - 可视区域高度 = 键盘高度
int screenHeight = container.getRootView().getHeight();
int keypadHeight = screenHeight - r.bottom;
// 如果键盘高度大于屏幕的 15%,说明键盘弹出了
if (keypadHeight > screenHeight * 0.15) {
// 键盘弹出:增加底部 Margin
updateBottomMargin(keypadHeight);
} else {
// 键盘收起:恢复原有 Margin (你代码中设置的是 dp2px(65))
updateBottomMargin(dp2px(65));
}
});
}
private void updateBottomMargin(int bottomPx) {
if (bottomContainer != null) {
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) bottomContainer.getLayoutParams();
if (params != null) {
// 动态设置底部间距
params.setMargins(dp2px(12), 0, dp2px(12), bottomPx);
bottomContainer.setLayoutParams(params);
}
}
}
private LinearLayout createDetailPanel(Context context) { private LinearLayout createDetailPanel(Context context) {
LinearLayout panel = new LinearLayout(context); LinearLayout panel = new LinearLayout(context);
panel.setOrientation(LinearLayout.VERTICAL); panel.setOrientation(LinearLayout.VERTICAL);
panel.setBackground(getRoundedDrawable(Color.WHITE, 16)); int padding = dp2px(15);
panel.setPadding(dp2px(20), dp2px(20), dp2px(20), dp2px(20)); panel.setPadding(padding, padding, padding, padding);
// --- (包含标题和关闭按钮) --- // --- (包含标题和关闭按钮) ---
LinearLayout titleLayout = new LinearLayout(context); LinearLayout titleLayout = new LinearLayout(context);
@@ -469,10 +369,7 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
ivClose.setScaleType(ImageView.ScaleType.CENTER_INSIDE); ivClose.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
ivClose.setPadding(dp2px(5), dp2px(5), dp2px(5), dp2px(5)); ivClose.setPadding(dp2px(5), dp2px(5), dp2px(5), dp2px(5));
ivClose.setOnClickListener(v -> { ivClose.setOnClickListener(v -> {
if (detailPanel != null) resetView();
detailPanel.setVisibility(View.GONE);
searchArea.setVisibility(View.VISIBLE);
planToggleBtn.setVisibility(View.VISIBLE);
}); });
LinearLayout.LayoutParams closeParams = new LinearLayout.LayoutParams(dp2px(28), dp2px(28)); LinearLayout.LayoutParams closeParams = new LinearLayout.LayoutParams(dp2px(28), dp2px(28));
@@ -480,6 +377,13 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
panel.addView(titleLayout); panel.addView(titleLayout);
//营业时间和地址
tvBusinessHours = new TextView(context);
tvBusinessHours.setTextSize(13);
tvBusinessHours.setPadding(0, dp2px(4), 0, 0);
tvBusinessHours.setTextColor(Color.GRAY);
panel.addView(tvBusinessHours);
tvStationAddr = new TextView(context); tvStationAddr = new TextView(context);
tvStationAddr.setTextSize(13); tvStationAddr.setTextSize(13);
tvStationAddr.setPadding(0, dp2px(4), 0, 0); tvStationAddr.setPadding(0, dp2px(4), 0, 0);
@@ -496,8 +400,8 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
row1.setOrientation(LinearLayout.HORIZONTAL); row1.setOrientation(LinearLayout.HORIZONTAL);
row1.setGravity(Gravity.CENTER_VERTICAL); row1.setGravity(Gravity.CENTER_VERTICAL);
row1.setPadding(0, dp2px(8), 0, 0); // 增加行间距 row1.setPadding(0, dp2px(8), 0, 0); // 增加行间距
tvDuration = createInfoItem(row1, R.drawable.ic_time, "预计时间:", "", 1.0f); tvDuration = createInfoItem(row1, R.drawable.ic_time, "预计时间:", "-", 1.0f);
tvTollsFuel = createInfoItem(row1, R.drawable.ic_fuel, "加氢费用:", "", 1.0f); tvTollsFuel = createInfoItem(row1, R.drawable.ic_fuel, "加氢费用:", "-", 1.0f);
routeInfoLayout.addView(row1); routeInfoLayout.addView(row1);
// 第二行:里程 + 过路费 // 第二行:里程 + 过路费
@@ -507,17 +411,34 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
row2.setPadding(0, dp2px(10), 0, 0); // 增加行间距 row2.setPadding(0, dp2px(10), 0, 0); // 增加行间距
// 里程 // 里程
tvDistance = createInfoItem(row2, R.drawable.ic_mileage, "行驶里程:", "", 1.0f); tvDistance = createInfoItem(row2, R.drawable.ic_mileage, "行驶里程:", "-", 1.0f);
// 过路费 // 过路费
tvTolls = createInfoItem(row2, R.drawable.ic_toll, "过路费:", "", 1.0f); tvTolls = createInfoItem(row2, R.drawable.ic_toll, "过路费:", "-", 1.0f);
routeInfoLayout.addView(row2); routeInfoLayout.addView(row2);
//第三行
LinearLayout row3 = new LinearLayout(context);
row3.setOrientation(LinearLayout.HORIZONTAL);
row3.setGravity(Gravity.CENTER_VERTICAL);
row3.setPadding(0, dp2px(8), 0, 0); // 增加行间距
tvPerson = createInfoItem(row3, R.drawable.ic_person, "站联系人:", "-", 1.0f);
tvPrice = createInfoItem(row3, R.drawable.ic_price, "加氢价格:", "-", 1.0f);
routeInfoLayout.addView(row3);
LinearLayout row4 = new LinearLayout(context);
row4.setOrientation(LinearLayout.HORIZONTAL);
row4.setGravity(Gravity.CENTER_VERTICAL);
row4.setPadding(0, dp2px(8), 0, 0); // 增加行间距
tvPhone = createInfoItem(row4, R.drawable.ic_phone, "联系方式:", "-", 1.0f);
routeInfoLayout.addView(row4);
panel.addView(routeInfoLayout); panel.addView(routeInfoLayout);
Button startNaviBtn = new Button(context); Button startNaviBtn = new Button(context);
startNaviBtn.setText("开始导航"); startNaviBtn.setText("开始导航");
startNaviBtn.setTextColor(Color.WHITE); startNaviBtn.setTextColor(Color.WHITE);
startNaviBtn.setBackground(getRoundedDrawable(Color.parseColor("#017143"), 10)); startNaviBtn.setBackground(getRoundedDrawable(Color.parseColor("#017143"), 99));
startNaviBtn.setOnClickListener(v -> startRouteSearch()); startNaviBtn.setOnClickListener(v -> startRouteSearch());
LinearLayout.LayoutParams btnParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, dp2px(48)); LinearLayout.LayoutParams btnParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, dp2px(48));
@@ -527,6 +448,15 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
return panel; return panel;
} }
private void resetView() {
if (detailPanel != null)
detailPanel.setVisibility(View.GONE);
searchArea.setVisibility(View.VISIBLE);
planToggleBtn.setVisibility(View.VISIBLE);
mLocBtn.setVisibility(View.VISIBLE);
}
private boolean isGetInputtips = false; private boolean isGetInputtips = false;
private void calculateRouteBeforeNavi() { private void calculateRouteBeforeNavi() {
@@ -543,107 +473,112 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
//如果是输入地址提示内容 //如果是输入地址提示内容
if (isGetInputtips) { if (isGetInputtips) {
// 开始规划前隐藏输入框面板 truckRouteData = null;
searchArea.setVisibility(View.GONE);
RouteSearch.FromAndTo fromAndTo = new RouteSearch.FromAndTo(new LatLonPoint(startPoint.latitude, startPoint.longitude), new LatLonPoint(endPoint.latitude, endPoint.longitude)); RouteSearch.FromAndTo fromAndTo = new RouteSearch.FromAndTo(new LatLonPoint(startPoint.latitude, startPoint.longitude), new LatLonPoint(endPoint.latitude, endPoint.longitude));
RouteSearch.DriveRouteQuery query = new RouteSearch.DriveRouteQuery(fromAndTo, RouteSearch.DRIVING_SINGLE_DEFAULT, null, null, ""); RouteSearch.DriveRouteQuery query = new RouteSearch.DriveRouteQuery(fromAndTo, RouteSearch.DRIVING_SINGLE_DEFAULT, null, null, "");
routeSearch.calculateDriveRouteAsyn(query); routeSearch.calculateDriveRouteAsyn(query);
// 开始规划前隐藏输入框面板
searchArea.setVisibility(View.GONE);
} else { } else {
fetchTruckRouteAlgorithm(mLoc); fetchTruckRouteAlgorithm(mLoc);
} }
} }
@Override
public void onGetInputtips(List<Tip> tipList, int rCode) {
if (rCode == 1000 && tipList != null && !tipList.isEmpty()) {
currentTipList.clear();
currentTipList.addAll(tipList);
List<String> suggestionNames = new ArrayList<>();
for (Tip tip : tipList) {
String name = tip.getName();
String district = tip.getDistrict();
// 在提示中显示名称和区域
String displayText = district != null && !district.isEmpty() ? name + " " + district : name;
suggestionNames.add(displayText);
}
suggestionAdapter.clear();
suggestionAdapter.addAll(suggestionNames);
suggestionAdapter.notifyDataSetChanged();
// 显示提示列表
new Handler(Looper.getMainLooper()).post(() -> {
if (suggestionNames.size() > 0) {
suggestionList.setVisibility(View.VISIBLE);
suggestionList.setBackgroundColor(Color.WHITE);
// 限制显示的高度
int height = Math.min(suggestionNames.size() * dp2px(45), dp2px(200));
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
height
);
suggestionList.setLayoutParams(params);
} else {
suggestionList.setVisibility(View.GONE);
}
});
} else {
// 请求失败或无结果,隐藏提示列表
new Handler(Looper.getMainLooper()).post(() -> suggestionList.setVisibility(View.GONE));
}
}
@Override @Override
public void onDriveRouteSearched(DriveRouteResult result, int rCode) { public void onDriveRouteSearched(DriveRouteResult result, int rCode) {
if (mActivity == null) {
Log.e(TAG, "mActivity is null in onDriveRouteSearched");
return;
}
mActivity.runOnUiThread(new Runnable() { mActivity.runOnUiThread(new Runnable() {
@Override @Override
public void run() { public void run() {
String hydrogenCost = "-"; // 默认显示横线
String hydrogenPrice = "-"; // 默认显示横线
String liaisonName = "-";
String liaisonPhone = "-";
String startBusiness = "-";
String endBusiness = "-";
double distanceKm = 0;
String distanceKmStr = "-";
long durationMin = 0;
String durationMinStr = "-";
String tolls = "-";
if (rCode == AMapException.CODE_AMAP_SUCCESS && result != null && !result.getPaths().isEmpty()) { if (rCode == AMapException.CODE_AMAP_SUCCESS && result != null && !result.getPaths().isEmpty()) {
DrivePath path = result.getPaths().get(0);
// 规划成功,显示详情面板,隐藏模式选择 // 规划成功,显示详情面板,隐藏模式选择
if (detailPanel != null) if (detailPanel != null)
detailPanel.setVisibility(View.VISIBLE); detailPanel.setVisibility(View.VISIBLE);
if (planToggleBtn != null) if (planToggleBtn != null)
planToggleBtn.setVisibility(View.GONE); planToggleBtn.setVisibility(View.GONE);
if (mLocBtn != null)
mLocBtn.setVisibility(View.GONE);
if (modeMenu != null) if (modeMenu != null)
modeMenu.setVisibility(View.GONE); modeMenu.setVisibility(View.GONE);
tvStationName.setText(endName); tvStationName.setText(endName);
tvStationAddr.setText(endAddress); tvStationAddr.setText(endAddress);
double distanceKm = path.getDistance() / 1000f;
long durationMin = path.getDuration() / 60;
double tolls = path.getTolls();
String hydrogenCost = "--"; // 默认显示横线 if (truckRouteData != null) {
try { PathDto pathDto = truckRouteData.pathDto;
// 增加多级非空校验,防止点击搜索条目时崩溃 if (pathDto != null) {
if (truckRouteData != null && distanceKm = pathDto.distance / 1000f;
truckRouteData.algorithmPath != null && durationMin = pathDto.duration / 60;
truckRouteData.algorithmPath.hydrogenCost != null && tolls = pathDto.tolls + "";
!truckRouteData.algorithmPath.hydrogenCost.isEmpty()) {
hydrogenCost = truckRouteData.algorithmPath.hydrogenCost; distanceKmStr = String.format("%.1f", distanceKm) + "公里";
durationMinStr = durationMin + "分钟";
} }
tvDuration.setText("预计时间:" + durationMin + "分钟");
tvDistance.setText("行驶里程:" + String.format("%.1f", distanceKm) + "公里");
tvTolls.setText("过路费:" + (int) tolls + "");
tvTollsFuel.setText("加氢费用:" + (isGetInputtips ? "--" : hydrogenCost) + "");
isGetInputtips = false;
aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(endPoint, 13f));
} catch (Exception e) {
Log.e(TAG, "获取加氢费用失败", e);
} }
// 增加多级非空校验,防止点击搜索条目时崩溃
if (truckRouteData != null &&
truckRouteData.algorithmPath != null &&
truckRouteData.algorithmPath.hydrogenCost != null &&
!truckRouteData.algorithmPath.hydrogenCost.isEmpty()) {
hydrogenCost = truckRouteData.algorithmPath.hydrogenCost;
hydrogenCost = (isGetInputtips ? "--" : hydrogenCost) + "";
}
tvDuration.setText("预计时间:" + durationMinStr);
tvDistance.setText("行驶里程:" + distanceKmStr);
tvTolls.setText("过路费:" + tolls);
tvTollsFuel.setText("预计加氢费用:" + hydrogenCost);
if (truckRouteData != null) {
DestinationSite destinationSite = truckRouteData.destinationSite;
if (destinationSite != null) {
startBusiness = destinationSite.startBusiness;
endBusiness = destinationSite.endBusiness;
hydrogenPrice = destinationSite.hydrogenPrice + "/L";
liaisonName = destinationSite.liaisonName;
liaisonPhone = destinationSite.liaisonPhone;
//开始结束时间
startBusiness = startBusiness + "-" + endBusiness;
}
}
tvBusinessHours.setText("营业时间:" + startBusiness);
if (liaisonName != null && liaisonName.length() > 5) {
liaisonName = liaisonName.substring(0, 5) + "...";
}
tvPerson.setText("站联系人:" + liaisonName);
tvPrice.setText("加氢价格:" + hydrogenPrice);
tvPhone.setText("联系方式:" + liaisonPhone);
aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(endPoint, 13f));
} else { } else {
// 规划失败回退面板 // 规划失败回退面板
searchArea.setVisibility(View.VISIBLE); searchArea.setVisibility(View.VISIBLE);
@@ -736,6 +671,11 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
// 检查途径点数量,决定使用哪种导航方式 // 检查途径点数量,决定使用哪种导航方式
int wayPointsCount = waysPoiIds.size(); int wayPointsCount = waysPoiIds.size();
Log.d(TAG, "途经点数量: " + wayPointsCount); Log.d(TAG, "途经点数量: " + wayPointsCount);
//如果是输入地址提示内容,不判断途经点
if (isGetInputtips) {
wayPointsCount = 0;
}
if (wayPointsCount > 3) { if (wayPointsCount > 3) {
// 途经点超过3个跳转到 NavigationActivity // 途经点超过3个跳转到 NavigationActivity
Intent intent = new Intent(mContext, NavigationActivity.class); Intent intent = new Intent(mContext, NavigationActivity.class);
@@ -802,13 +742,11 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
* 获取货车路线算法信息 * 获取货车路线算法信息
*/ */
private void fetchTruckRouteAlgorithm(AMapLocation loc) { private void fetchTruckRouteAlgorithm(AMapLocation loc) {
showLoading();
if (plateNumber == null || plateNumber.isEmpty()) { if (plateNumber == null || plateNumber.isEmpty()) {
Toast.makeText(mActivity, "请先绑定车辆后进行导航", Toast.LENGTH_SHORT).show();
return; return;
} }
showLoading();
try { try {
JSONObject json = new JSONObject(); JSONObject json = new JSONObject();
json.put("longitude", String.valueOf(loc.getLongitude())); json.put("longitude", String.valueOf(loc.getLongitude()));
@@ -923,11 +861,18 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
aMap.setMyLocationEnabled(true); aMap.setMyLocationEnabled(true);
aMap.setOnMarkerClickListener(this); aMap.setOnMarkerClickListener(this);
// 添加地图触摸监听器,点击地图时隐藏提示列表 // 添加地图点击监听,当 detailPanel 显示时点击地图就执行 resetView
aMap.setOnMapClickListener(latLng -> { aMap.setOnMapClickListener(latLng -> {
if (suggestionList != null && suggestionList.getVisibility() == View.VISIBLE) { if (detailPanel != null && detailPanel.getVisibility() == View.VISIBLE) {
suggestionList.setVisibility(View.GONE); resetView();
} }
modeMenu.setVisibility(View.GONE);
});
aMap.setOnPOIClickListener(poi -> {
if (detailPanel != null && detailPanel.getVisibility() == View.VISIBLE) {
resetView();
}
modeMenu.setVisibility(View.GONE);
}); });
MyLocationStyle myLocationStyle = new MyLocationStyle(); MyLocationStyle myLocationStyle = new MyLocationStyle();
@@ -942,7 +887,7 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
} }
myLocationStyle.anchor(0.5f, 0.5f); myLocationStyle.anchor(0.5f, 0.5f);
myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER); myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_SHOW);
aMap.setMyLocationStyle(myLocationStyle); aMap.setMyLocationStyle(myLocationStyle);
aMap.getUiSettings().setZoomControlsEnabled(false); aMap.getUiSettings().setZoomControlsEnabled(false);
aMap.getUiSettings().setLogoPosition(AMapOptions.LOGO_POSITION_BOTTOM_LEFT); aMap.getUiSettings().setLogoPosition(AMapOptions.LOGO_POSITION_BOTTOM_LEFT);
@@ -973,6 +918,33 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
mlocationClient.stopLocation(); mlocationClient.stopLocation();
} }
public void setDestination(String name, String address, double lat, double lon, String district) {
endName = name;
endAddress = address;
endPoint = new LatLng(lat, lon);
isUserSelectedDestination = true;
isGetInputtips = true;
Log.d(TAG, "setDestination called with name=" + name);
// 简化逻辑,直接设置文本
endInput.post(() -> {
try {
endInput.setText(district != null && !district.isEmpty() ? (name + " " + district) : name);
} catch (Exception e) {
Log.e(TAG, "Failed to set text to endInput", e);
}
});
}
/**
* 设置 Activity 实例
*/
public void setActivity(Activity activity) {
this.mActivity = activity;
}
public void startLocation() { public void startLocation() {
if (mlocationClient == null) { if (mlocationClient == null) {
try { try {
@@ -1127,6 +1099,7 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
dataMap.put("latLng", latLng); dataMap.put("latLng", latLng);
dataMap.put("stationId", stationId); dataMap.put("stationId", stationId);
dataMap.put("address", address); dataMap.put("address", address);
dataMap.put("name", name);
m.setObject(dataMap); m.setObject(dataMap);
stationMarkers.add(m); stationMarkers.add(m);
@@ -1137,7 +1110,27 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
//地图选点 //地图选点
for (Marker m : stationMarkers) { for (Marker m : stationMarkers) {
m.setIcon(BitmapDescriptorFactory.fromResource(m.equals(marker) ? R.drawable.ic_marker : R.drawable.ic_un_marker)); Object obj = m.getObject();
if (obj instanceof Map) {
Map<String, Object> dataMap = (Map<String, Object>) obj;
String name = (String) dataMap.get("name");
if (name != null) {
// 截取显示名称最多7个字符
String displayName = name.length() > 7 ? name.substring(0, 7) + "..." :
name;
boolean isSelected = m.equals(marker);
// 使用 getMarkerIconWithText 创建带文字的图标
BitmapDescriptor icon = getMarkerIconWithText(mContext, displayName,
isSelected);
m.setIcon(icon);
} else {
// 如果没有 name降级到直接设置图标
m.setIcon(BitmapDescriptorFactory.fromResource(m.equals(marker) ?
R.drawable.ic_marker : R.drawable.ic_un_marker));
}
}
} }
@@ -1162,6 +1155,9 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
// 更新 UI 和 业务逻辑 // 更新 UI 和 业务逻辑
endName = marker.getTitle(); endName = marker.getTitle();
isUserSelectedDestination = true; // 标识用户手动选择了目的地 isUserSelectedDestination = true; // 标识用户手动选择了目的地
isGetInputtips = false;
endInput.setText("");
// 需要传入当前位置以便接口计算路线 // 需要传入当前位置以便接口计算路线
if (mlocationClient != null && mlocationClient.getLastKnownLocation() != null) { if (mlocationClient != null && mlocationClient.getLastKnownLocation() != null) {
@@ -1306,9 +1302,12 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
// 文本内容 // 文本内容
TextView tv = new TextView(mContext); TextView tv = new TextView(mContext);
tv.setText(label + value); tv.setText(label + value);
tv.setTextSize(14);
tv.setTextColor(Color.parseColor("#333333")); tv.setTextSize(12);
tv.setTextColor(Color.parseColor("#ff1d2129"));
tv.setPadding(dp2px(6), 0, 0, 0); tv.setPadding(dp2px(6), 0, 0, 0);
LinearLayout.LayoutParams tvParams = new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 1.0f); LinearLayout.LayoutParams tvParams = new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 1.0f);
@@ -1321,23 +1320,6 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
return tv; // 返回TextView以便后续更新内容 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) { private View createModeMenu(Context context) {
@@ -1360,9 +1342,9 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
TextView item3 = createMenuItem(context, "加氢规划模式", true); TextView item3 = createMenuItem(context, "加氢规划模式", true);
item3.setOnClickListener(v -> switchMode("加氢规划")); item3.setOnClickListener(v -> switchMode("加氢规划"));
menu.addView(item1);
menu.addView(item2);
menu.addView(item3); menu.addView(item3);
menu.addView(item2);
menu.addView(item1);
return menu; return menu;
} }
@@ -1373,13 +1355,12 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
tv.setPadding(dp2px(15), dp2px(12), dp2px(15), dp2px(12)); tv.setPadding(dp2px(15), dp2px(12), dp2px(15), dp2px(12));
tv.setGravity(Gravity.CENTER); tv.setGravity(Gravity.CENTER);
if (isHighlight) { if (isHighlight) {
tv.setTextColor(Color.WHITE);
// 顶部圆角绿色背景 // 顶部圆角绿色背景
tv.setBackground(getTopRoundedDrawable(Color.parseColor("#27AE60"), 12)); tv.setBackground(getTopRoundedDrawable(Color.parseColor("#27AE60"), 12));
} else { } else {
tv.setTextColor(Color.parseColor("#666666"));
tv.setBackgroundColor(Color.TRANSPARENT); tv.setBackgroundColor(Color.TRANSPARENT);
} }
tv.setTextColor(Color.parseColor(isHighlight ? "#ffffffff" : "#ffc9cdd4"));
return tv; return tv;
} }
@@ -1463,6 +1444,9 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
destinationSite.longitude = siteJson.optString("longitude", ""); destinationSite.longitude = siteJson.optString("longitude", "");
destinationSite.latitude = siteJson.optString("latitude", ""); destinationSite.latitude = siteJson.optString("latitude", "");
destinationSite.distance = siteJson.optString("distance", ""); destinationSite.distance = siteJson.optString("distance", "");
destinationSite.hydrogenPrice = siteJson.optString("hydrogenPrice", "");
destinationSite.liaisonName = siteJson.optString("liaisonName", "");
destinationSite.liaisonPhone = siteJson.optString("liaisonPhone", "");
truckRouteData.destinationSite = destinationSite; truckRouteData.destinationSite = destinationSite;
} }
@@ -1660,5 +1644,9 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
public String longitude; public String longitude;
public String latitude; public String latitude;
public String distance; public String distance;
public String hydrogenPrice;
public String liaisonName;
public String liaisonPhone;
} }
} }

View File

@@ -187,6 +187,7 @@ public class NavigationActivity extends ComponentActivity implements AMapNaviLis
mAMapNavi.setCarInfo(carInfo); mAMapNavi.setCarInfo(carInfo);
} }
mAMapNavi.setUseInnerVoice(true);
// 计算并启动导航 // 计算并启动导航
mAMapNavi.calculateDriveRoute(startNaviPoi, endNaviPoi, wayPoints, PathPlanningStrategy.DRIVING_MULTIPLE_ROUTES_DEFAULT); mAMapNavi.calculateDriveRoute(startNaviPoi, endNaviPoi, wayPoints, PathPlanningStrategy.DRIVING_MULTIPLE_ROUTES_DEFAULT);

View File

@@ -0,0 +1,261 @@
package com.lnkj.ln_jq_app;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import com.amap.api.services.help.Inputtips;
import com.amap.api.services.help.InputtipsQuery;
import com.amap.api.services.help.Tip;
import java.util.ArrayList;
import java.util.List;
import androidx.activity.ComponentActivity;
/**
* 搜索目的地页面
*/
public class SearchDestinationActivity extends ComponentActivity implements Inputtips.InputtipsListener {
private static final String TAG = "SearchDestinationActivity";
public static final String EXTRA_RESULT_NAME = "result_name";
public static final String EXTRA_RESULT_ADDRESS = "result_address";
public static final String EXTRA_RESULT_LAT = "result_lat";
public static final String EXTRA_RESULT_LON = "result_lon";
public static final String EXTRA_RESULT_DISTRICT = "result_district";
// 静态回调接口
public interface DestinationCallback {
void onDestinationSelected(String name, String address, double lat, double lon, String district);
}
private static DestinationCallback callback;
public static void setCallback(DestinationCallback callback) {
SearchDestinationActivity.callback = callback;
}
private EditText searchInput;
private ListView suggestionList;
private ImageView backBtn;
private ArrayAdapter<String> suggestionAdapter;
private List<Tip> currentTipList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
setContentView(R.layout.activity_search_destination);
initViews();
setupListeners();
// 自动显示键盘
showKeyboard();
} catch (Exception e) {
Log.e(TAG, "Error in onCreate", e);
e.printStackTrace();
finish();
}
}
private void initViews() {
try {
Log.d(TAG, "initViews started");
searchInput = findViewById(R.id.search_input);
suggestionList = findViewById(R.id.suggestion_list);
backBtn = findViewById(R.id.back_btn);
currentTipList = new ArrayList<>();
Log.d(TAG, "initViews completed: searchInput=" + (searchInput != null ? "ok" : "null") + ", suggestionList=" + (suggestionList != null ? "ok" : "null") + ", backBtn=" + (backBtn != null ? "ok" : "null"));
} catch (Exception e) {
Log.e(TAG, "Error in initViews", e);
e.printStackTrace();
}
suggestionAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, new ArrayList<>()) {
@Override
public View getView(int position, android.view.View convertView, android.view.ViewGroup parent) {
View view = super.getView(position, convertView, parent);
TextView text = view.findViewById(android.R.id.text1);
text.setTextColor(Color.parseColor("#333333"));
text.setTextSize(14);
view.setBackgroundColor(Color.TRANSPARENT);
return view;
}
};
suggestionList.setAdapter(suggestionAdapter);
suggestionList.setDivider(new ColorDrawable(Color.LTGRAY));
suggestionList.setDividerHeight(1);
}
private void setupListeners() {
try {
Log.d(TAG, "setupListeners started");
// 返回按钮
backBtn.setOnClickListener(v -> {
Log.d(TAG, "Back button clicked");
hideKeyboard();
finish();
});
// 文本变化监听
searchInput.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
Log.d(TAG, "Text changed: " + (s != null ? s.toString() : "null") + ", length=" + (s != null ? s.length() : 0));
if (s.length() > 1) {
searchLocation(s.toString());
} else {
suggestionList.setVisibility(View.GONE);
}
}
@Override
public void afterTextChanged(Editable s) {
}
});
// 列表点击
suggestionList.setOnItemClickListener((parent, view, position, id) -> {
Log.d(TAG, "Suggestion clicked at position: " + position);
try {
Tip tip = currentTipList.get(position);
if (tip.getPoint() != null) {
String name = tip.getName();
String address = tip.getAddress();
String district = tip.getDistrict();
double lat = tip.getPoint().getLatitude();
double lon = tip.getPoint().getLongitude();
Log.d(TAG, "Selected destination: " + name + ", lat=" + lat + ", lon=" + lon);
// 优先使用静态回调
if (callback != null) {
callback.onDestinationSelected(name, address, lat, lon, district);
} else {
// 降级使用 Intent 回调
Intent result = new Intent();
result.putExtra(EXTRA_RESULT_NAME, name);
result.putExtra(EXTRA_RESULT_ADDRESS, address);
result.putExtra(EXTRA_RESULT_LAT, lat);
result.putExtra(EXTRA_RESULT_LON, lon);
result.putExtra(EXTRA_RESULT_DISTRICT, district);
setResult(RESULT_OK, result);
}
hideKeyboard();
finish();
}
} catch (Exception e) {
Log.e(TAG, "Error handling suggestion click", e);
e.printStackTrace();
}
});
Log.d(TAG, "setupListeners completed");
} catch (Exception e) {
Log.e(TAG, "Error in setupListeners", e);
e.printStackTrace();
}
}
private void searchLocation(String keyword) {
try {
Log.d(TAG, "Searching for: " + keyword);
InputtipsQuery query = new InputtipsQuery(keyword, "");
query.setCityLimit(false);
Inputtips inputtips = new Inputtips(this, query);
inputtips.setInputtipsListener(this);
inputtips.requestInputtipsAsyn();
} catch (Exception e) {
Log.e(TAG, "Error in searchLocation", e);
e.printStackTrace();
}
}
@Override
public void onGetInputtips(List<Tip> tipList, int rCode) {
Log.d(TAG, "onGetInputtips called, rCode=" + rCode + ", tipList size=" + (tipList != null ? tipList.size() : "null"));
if (rCode == 1000 && tipList != null && !tipList.isEmpty()) {
currentTipList.clear();
currentTipList.addAll(tipList);
List<String> suggestionNames = new ArrayList<>();
for (Tip tip : tipList) {
String name = tip.getName();
String district = tip.getDistrict();
String displayText = district != null && !district.isEmpty() ? name + " " + district : name;
suggestionNames.add(displayText);
}
runOnUiThread(() -> {
suggestionAdapter.clear();
suggestionAdapter.addAll(suggestionNames);
suggestionAdapter.notifyDataSetChanged();
if (suggestionNames.size() > 0) {
suggestionList.setVisibility(View.VISIBLE);
} else {
suggestionList.setVisibility(View.GONE);
}
});
} else {
runOnUiThread(() -> {
suggestionList.setVisibility(View.GONE);
});
}
}
private void showKeyboard() {
searchInput.requestFocus();
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm != null) {
imm.showSoftInput(searchInput, InputMethodManager.SHOW_IMPLICIT);
}
}
private void hideKeyboard() {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm != null) {
imm.hideSoftInputFromWindow(searchInput.getWindowToken(), 0);
}
}
@Override
public void onPointerCaptureChanged(boolean hasCapture) {
super.onPointerCaptureChanged(hasCapture);
}
@Override
protected void onDestroy() {
super.onDestroy();
// 清理回调,避免内存泄漏
callback = null;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 705 B

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 背景颜色:使用浅灰色 -->
<solid android:color="#ffffffff" />
<!-- 圆角8dp左右 -->
<corners android:radius="8dp" />
<!-- 边框:可选,如果需要更清晰的边缘可以加上 -->
<stroke android:width="1dp" android:color="#EAEAEA" />
</shape>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,40 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="16dp"
android:viewportWidth="16"
android:viewportHeight="16">
<path
android:strokeWidth="1"
android:pathData="M8,14.667C10.946,14.667 13.333,12.496 13.333,9.818C13.333,7.192 11.556,4.364 8,1.333C4.444,4.364 2.667,7.192 2.667,9.818C2.667,12.496 5.054,14.667 8,14.667Z"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="#017137"/>
<path
android:strokeWidth="1"
android:pathData="M6.286,6.333L8,8.123L9.714,6.333"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="#017137"
android:strokeLineCap="round"/>
<path
android:strokeWidth="1"
android:pathData="M6,8.719H10"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="#017137"
android:strokeLineCap="round"/>
<path
android:strokeWidth="1"
android:pathData="M6,10.509H10"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="#017137"
android:strokeLineCap="round"/>
<path
android:strokeWidth="1"
android:pathData="M8,8.719V12"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="#017137"
android:strokeLineCap="round"/>
</vector>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,41 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="16dp"
android:viewportWidth="16"
android:viewportHeight="16">
<path
android:strokeWidth="1"
android:pathData="M3.667,1.375L2,13.375"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="#017137"
android:strokeLineCap="round"/>
<path
android:strokeWidth="1"
android:pathData="M12.333,1.375L13.988,13.36"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="#017137"
android:strokeLineCap="round"/>
<path
android:strokeWidth="1"
android:pathData="M8,1.375V3.375"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="#017137"
android:strokeLineCap="round"/>
<path
android:strokeWidth="1"
android:pathData="M8,11.042V13.375"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="#017137"
android:strokeLineCap="round"/>
<path
android:strokeWidth="1"
android:pathData="M8,6.042V8.375"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="#017137"
android:strokeLineCap="round"/>
</vector>

View File

@@ -0,0 +1,13 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<group>
<clip-path
android:pathData="M0,0h24v24h-24z"/>
<path
android:pathData="M6.518,10.241C4.181,10.241 2.29,12.135 2.29,14.469C2.29,16.804 6.518,21.684 6.518,21.684C6.518,21.684 10.746,16.806 10.746,14.469C10.746,12.133 8.853,10.241 6.518,10.241ZM6.518,15.616C5.853,15.616 5.313,15.077 5.313,14.411C5.313,13.745 5.853,13.206 6.518,13.206C7.184,13.206 7.723,13.745 7.723,14.411C7.723,15.077 7.181,15.616 6.518,15.616ZM19.676,2.301C18.567,2.301 17.67,3.198 17.67,4.307C17.67,5.416 19.676,7.729 19.676,7.729C19.676,7.729 21.682,5.416 21.682,4.307C21.682,3.198 20.785,2.301 19.676,2.301ZM19.676,4.851C19.36,4.851 19.104,4.595 19.104,4.279C19.104,3.963 19.36,3.707 19.676,3.707C19.992,3.707 20.248,3.963 20.248,4.279C20.246,4.595 19.99,4.851 19.676,4.851ZM18.026,13.185C17.386,12.813 16.629,12.674 15.898,12.538C14.845,12.344 14.196,12.191 14.074,11.72C14.051,11.627 14.037,11.493 14.156,11.291C14.325,11.005 14.855,10.422 16.519,9.735C16.993,9.539 17.449,9.382 17.801,9.27C18.168,9.153 18.393,8.768 18.296,8.395C18.199,8.019 17.812,7.792 17.442,7.909C17.056,8.03 16.543,8.205 15.999,8.43C14.431,9.074 13.404,9.798 12.945,10.579C12.663,11.057 12.584,11.575 12.713,12.077C12.877,12.709 13.303,13.185 13.978,13.485C14.482,13.71 15.073,13.818 15.642,13.923C16.256,14.036 16.889,14.153 17.318,14.402C17.597,14.563 17.888,14.819 17.916,15.487C17.958,16.427 16.88,17.448 14.881,18.367C13.833,18.848 12.764,19.192 12.099,19.385C11.729,19.493 11.5,19.869 11.589,20.244C11.68,20.625 12.064,20.86 12.441,20.752C13.144,20.55 14.295,20.183 15.45,19.654C16.547,19.152 17.424,18.606 18.054,18.032C18.938,17.228 19.364,16.349 19.322,15.426C19.278,14.413 18.842,13.661 18.026,13.185Z"
android:fillColor="#ffffff"/>
</group>
</vector>

View File

@@ -0,0 +1,20 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="16dp"
android:viewportWidth="16"
android:viewportHeight="16">
<path
android:strokeWidth="1"
android:pathData="M8,6.042C9.289,6.042 10.333,4.997 10.333,3.708C10.333,2.42 9.289,1.375 8,1.375C6.711,1.375 5.667,2.42 5.667,3.708C5.667,4.997 6.711,6.042 8,6.042Z"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="#017137"
android:strokeLineCap="round"/>
<path
android:strokeWidth="1"
android:pathData="M2,12.975V13.375H14V12.975C14,11.481 14,10.735 13.709,10.164C13.454,9.663 13.046,9.255 12.544,8.999C11.974,8.708 11.227,8.708 9.733,8.708H6.267C4.773,8.708 4.026,8.708 3.456,8.999C2.954,9.255 2.546,9.663 2.291,10.164C2,10.735 2,11.481 2,12.975Z"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="#017137"
android:strokeLineCap="round"/>
</vector>

View File

@@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="16dp"
android:viewportWidth="16"
android:viewportHeight="16">
<path
android:strokeWidth="1"
android:pathData="M5.665,1.937C5.908,1.937 6.131,2.068 6.248,2.28L7.064,3.749C7.171,3.941 7.176,4.174 7.077,4.371L6.292,5.942C6.292,5.942 6.519,7.112 7.472,8.065C8.425,9.018 9.591,9.242 9.591,9.242L11.162,8.456C11.359,8.358 11.592,8.363 11.785,8.47L13.258,9.289C13.469,9.407 13.6,9.63 13.6,9.872V11.563C13.6,12.424 12.8,13.046 11.984,12.771C10.308,12.205 7.707,11.128 6.058,9.479C4.409,7.831 3.332,5.229 2.767,3.553C2.491,2.737 3.113,1.937 3.975,1.937H5.665Z"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="#017137"/>
</vector>

View File

@@ -0,0 +1,40 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="16dp"
android:viewportWidth="16"
android:viewportHeight="16">
<path
android:strokeWidth="1"
android:pathData="M8,14.042C11.682,14.042 14.667,11.057 14.667,7.375C14.667,3.693 11.682,0.708 8,0.708C4.318,0.708 1.333,3.693 1.333,7.375C1.333,11.057 4.318,14.042 8,14.042Z"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="#017137"/>
<path
android:strokeWidth="1"
android:pathData="M6,6.708H10"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="#017137"
android:strokeLineCap="round"/>
<path
android:strokeWidth="1"
android:pathData="M6,8.708H10"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="#017137"
android:strokeLineCap="round"/>
<path
android:strokeWidth="1"
android:pathData="M8.003,6.708V10.708"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="#017137"
android:strokeLineCap="round"/>
<path
android:strokeWidth="1"
android:pathData="M10,4.375L8,6.375L6,4.375"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="#017137"
android:strokeLineCap="round"/>
</vector>

View File

@@ -0,0 +1,26 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="18dp"
android:height="18dp"
android:viewportWidth="18"
android:viewportHeight="18">
<path
android:strokeWidth="1"
android:pathData="M7.875,14.5C11.396,14.5 14.25,11.646 14.25,8.125C14.25,4.604 11.396,1.75 7.875,1.75C4.354,1.75 1.5,4.604 1.5,8.125C1.5,11.646 4.354,14.5 7.875,14.5Z"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="#4E5969"/>
<path
android:strokeWidth="1"
android:pathData="M9.997,5.629C9.454,5.086 8.704,4.75 7.875,4.75C7.047,4.75 6.297,5.086 5.754,5.629"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="#4E5969"
android:strokeLineCap="round"/>
<path
android:strokeWidth="1"
android:pathData="M12.458,12.707L15.64,15.889"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="#4E5969"
android:strokeLineCap="round"/>
</vector>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 810 B

View File

@@ -0,0 +1,19 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="16dp"
android:viewportWidth="16"
android:viewportHeight="16">
<path
android:strokeWidth="1"
android:pathData="M8,14.042C11.682,14.042 14.667,11.057 14.667,7.375C14.667,3.693 11.682,0.708 8,0.708C4.318,0.708 1.333,3.693 1.333,7.375C1.333,11.057 4.318,14.042 8,14.042Z"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="#017137"/>
<path
android:strokeWidth="1"
android:pathData="M8.003,3.375L8.003,7.378L10.829,10.204"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="#017137"
android:strokeLineCap="round"/>
</vector>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 924 B

View File

@@ -0,0 +1,37 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="16dp"
android:viewportWidth="16"
android:viewportHeight="16">
<path
android:strokeWidth="1"
android:pathData="M1.333,2.042H3.667C3.667,2.042 4,3.708 5.667,3.708C7.333,3.708 7.667,2.042 7.667,2.042H14.667V12.708H7.667C7.667,12.708 7.333,11.042 5.667,11.042C4,11.042 3.667,12.708 3.667,12.708H1.333V2.042Z"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="#017137"
android:strokeLineCap="round"/>
<path
android:strokeWidth="1"
android:pathData="M5.667,5.708V6.375"
android:fillColor="#00000000"
android:strokeColor="#017137"
android:strokeLineCap="round"/>
<path
android:strokeWidth="1"
android:pathData="M5.667,8.375V9.042"
android:fillColor="#00000000"
android:strokeColor="#017137"
android:strokeLineCap="round"/>
<path
android:strokeWidth="1"
android:pathData="M8.333,6.375H12"
android:fillColor="#00000000"
android:strokeColor="#017137"
android:strokeLineCap="round"/>
<path
android:strokeWidth="1"
android:pathData="M8.333,8.375H12"
android:fillColor="#00000000"
android:strokeColor="#017137"
android:strokeLineCap="round"/>
</vector>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#FFFFFF" />
<corners
android:topLeftRadius="24dp"
android:topRightRadius="24dp"
android:bottomLeftRadius="0dp"
android:bottomRightRadius="0dp" />
</shape>

View File

@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="55dp"
android:gravity="center">
<ImageView
android:id="@+id/back_btn"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginStart="10dp"
android:src="@drawable/back" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:text="选择地点"
android:textColor="#000000"
android:textSize="18sp" />
</LinearLayout>
<EditText
android:id="@+id/search_input"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_margin="12dp"
android:background="@drawable/bg_search_input"
android:hint="输入地址"
android:imeOptions="actionDone"
android:paddingStart="12dp"
android:paddingEnd="12dp"
android:singleLine="true"
android:textColor="#333333"
android:textColorHint="#999999"
android:textSize="14sp" />
<ListView
android:id="@+id/suggestion_list"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:padding="8dp"
android:visibility="gone" />
</LinearLayout>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 844 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 792 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 909 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 864 B

View File

@@ -0,0 +1,30 @@
//
// AAddHPopView.h
// AMapNavIOSSDK
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
/**
* 气泡弹框视图
*
* 用法:
* AAddHPopView *pop = [[AAddHPopView alloc] init];
* [pop showInView:self.view sourceView:addHbtn];
*
* - 点击气泡外部自动消失
* - 箭头在右下角45度指向 sourceView 中心
*/
@interface AAddHPopView : UIView
/// 展示气泡sourceView 为箭头指向的锚定按钮(坐标系属于 view
- (void)showInView:(UIView *)view sourceView:(UIView *)sourceView;
/// 手动消失(点击空白处会自动调用)
- (void)dismiss;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,359 @@
//
// AAddHPopView.m
// AMapNavIOSSDK
//
#import "AAddHPopView.h"
#import <Masonry/Masonry.h>
#import "UIColor+ANavMap.h"
//
static const CGFloat kBubbleWidth = 200.f; //
static const CGFloat kHeaderHeight = 50.f; // 绿
static const CGFloat kOptionHeight = 60.f; //
static const CGFloat kArrowWidth = 50.f; // aw = ah*2 使45
static const CGFloat kArrowHeight = 15.f; //
static const CGFloat kBubbleRadius = 15.f; //
static const CGFloat kBubbleGap = 5.f; // sourceView
static const CGFloat kScreenPadding = 15.f; //
// +
@interface _ABubbleContainerView : UIView
/// X view showInView
@property (nonatomic, assign) CGFloat arrowCenterX;
@end
@implementation _ABubbleContainerView
- (instancetype)init {
self = [super init];
if (self) {
self.backgroundColor = [UIColor clearColor];
_arrowCenterX = kBubbleWidth / 2.f;
}
return self;
}
- (void)setArrowCenterX:(CGFloat)arrowCenterX {
_arrowCenterX = arrowCenterX;
[self setNeedsDisplay];
}
- (void)drawRect:(CGRect)rect {
CGFloat bw = kBubbleWidth; // 160
CGFloat bh = kHeaderHeight + kOptionHeight * 2.f; // 150
CGFloat r = kBubbleRadius; // 10
CGFloat aw = kArrowWidth; // 16
CGFloat ah = kArrowHeight; // 10
// 45
// : (arrowX-aw/2, bh) (arrowX, bh)
// : (arrowX + ah, bh + ah) 45
CGFloat arrowX = bw - 15.f; // X
CGFloat arrowTipX = arrowX + ah; // Xah = 45
CGFloat arrowTipY = bh + ah; // Yah = 45
UIBezierPath *path = [UIBezierPath bezierPath];
//
[path moveToPoint:CGPointMake(r, 0)];
[path addLineToPoint:CGPointMake(bw - r, 0)];
[path addArcWithCenter:CGPointMake(bw - r, r) radius:r
startAngle:-M_PI_2 endAngle:0 clockwise:YES];
//
[path addLineToPoint:CGPointMake(bw, bh - r)];
[path addArcWithCenter:CGPointMake(bw - r, bh - r) radius:r
startAngle:0 endAngle:M_PI_2 clockwise:YES];
//
[path addLineToPoint:CGPointMake(arrowX, bh)];
// 45
[path addLineToPoint:CGPointMake(arrowTipX, arrowTipY)];
//
[path addLineToPoint:CGPointMake(arrowX - ah, bh)];
//
[path addArcWithCenter:CGPointMake(r, bh - r) radius:r
startAngle:M_PI_2 endAngle:M_PI clockwise:YES];
//
[path addLineToPoint:CGPointMake(0, r)];
[path addArcWithCenter:CGPointMake(r, r) radius:r
startAngle:M_PI endAngle:-M_PI_2 clockwise:YES];
[path closePath];
// +
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSaveGState(ctx);
CGContextSetShadowWithColor(ctx, CGSizeMake(0, 3), 10.f,
[[UIColor blackColor] colorWithAlphaComponent:0.15f].CGColor);
[[UIColor whiteColor] setFill];
[path fill];
CGContextRestoreGState(ctx);
[[UIColor whiteColor] setFill];
[path fill];
//
_arrowTipX = arrowTipX;
_arrowTipY = arrowTipY;
}
// 访
static CGFloat _arrowTipX = 0;
static CGFloat _arrowTipY = 0;
@end
// AAddHPopView
@interface AAddHPopView ()
@property (nonatomic, strong) _ABubbleContainerView *bubbleContainer;
@property (nonatomic, strong) UIView *headerView;
@property (nonatomic, strong) UILabel *titleLabel;
@property (nonatomic, strong) UIView *separatorLine1;
@property (nonatomic, strong) UILabel *option1Label;
@property (nonatomic, strong) UIView *separatorLine2;
@property (nonatomic, strong) UILabel *option2Label;
@end
@implementation AAddHPopView
#pragma mark - Init
- (instancetype)init {
return [self initWithFrame:CGRectZero];
}
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self p_setupUI];
}
return self;
}
#pragma mark - Setup UI
- (void)p_setupUI {
self.backgroundColor = [UIColor clearColor];
// self
UITapGestureRecognizer *bgTap = [[UITapGestureRecognizer alloc] initWithTarget:self
action:@selector(dismiss)];
bgTap.cancelsTouchesInView = NO;
[self addGestureRecognizer:bgTap];
//
[self addSubview:self.bubbleContainer];
// header绿
[self.bubbleContainer addSubview:self.headerView];
[self.headerView addSubview:self.titleLabel];
// 线 1
[self.bubbleContainer addSubview:self.separatorLine1];
// 1
[self.bubbleContainer addSubview:self.option1Label];
// 线 2
[self.bubbleContainer addSubview:self.separatorLine2];
// 2
[self.bubbleContainer addSubview:self.option2Label];
// bgTap
UITapGestureRecognizer *bubbleTap = [[UITapGestureRecognizer alloc] initWithTarget:self
action:@selector(p_bubbleTapped)];
[self.bubbleContainer addGestureRecognizer:bubbleTap];
// Masonry bubbleContainer
// kBubbleWidth160
[self.headerView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.left.equalTo(self.bubbleContainer);
make.width.mas_equalTo(kBubbleWidth);
make.height.mas_equalTo(kHeaderHeight);
}];
[self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.headerView);
}];
[self.separatorLine1 mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.headerView.mas_bottom);
make.left.mas_equalTo(@0);
make.width.mas_equalTo(kBubbleWidth);
make.height.mas_equalTo(0.5);
}];
[self.option1Label mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.separatorLine1.mas_bottom);
make.left.mas_equalTo(@0);
make.width.mas_equalTo(kBubbleWidth);
make.height.mas_equalTo(kOptionHeight);
}];
[self.separatorLine2 mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.option1Label.mas_bottom);
make.left.mas_equalTo(@0);
make.width.mas_equalTo(kBubbleWidth);
make.height.mas_equalTo(0.5);
}];
[self.option2Label mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.separatorLine2.mas_bottom);
make.left.mas_equalTo(@0);
make.width.mas_equalTo(kBubbleWidth);
make.height.mas_equalTo(kOptionHeight);
}];
}
#pragma mark - Show / Dismiss
- (void)showInView:(UIView *)view sourceView:(UIView *)sourceView {
self.frame = view.bounds;
[view addSubview:self];
// sourceView view frame
CGRect srcFrame = [sourceView convertRect:sourceView.bounds toView:view];
//
CGFloat containerW = kBubbleWidth; // 160
CGFloat containerH = kHeaderHeight + kOptionHeight * 2.f; // 150
CGFloat ah = kArrowHeight; // 16
// bubbleContainer
// drawRect arrowX = bw - 35, arrowTipX = arrowX + ah
CGFloat arrowX_inContainer = containerW - 25.f; // X
CGFloat arrowTipX_inContainer = arrowX_inContainer + ah; // X45
CGFloat arrowTipY_inContainer = containerH + ah; // Y
//
CGFloat srcCenterX = CGRectGetMidX(srcFrame);
CGFloat srcCenterY = CGRectGetMidY(srcFrame);
//
CGFloat containerX = srcCenterX - arrowTipX_inContainer;
containerX = MAX(kScreenPadding, MIN(containerX, view.bounds.size.width - containerW - kScreenPadding));
//
CGFloat containerY = srcCenterY - arrowTipY_inContainer;
containerY = MAX(kScreenPadding, containerY);
self.bubbleContainer.bounds = CGRectMake(0, 0, containerW, containerH + ah);
//
self.bubbleContainer.layer.anchorPoint = CGPointMake(arrowTipX_inContainer / containerW,
arrowTipY_inContainer / (containerH + ah));
self.bubbleContainer.center = CGPointMake(srcCenterX - 25, srcCenterY - 20);
//
self.alpha = 0.f;
self.bubbleContainer.transform = CGAffineTransformMakeScale(0.85f, 0.85f);
[UIView animateWithDuration:0.25f
delay:0.f
usingSpringWithDamping:0.72f
initialSpringVelocity:0.3f
options:UIViewAnimationOptionCurveEaseOut
animations:^{
self.alpha = 1.f;
self.bubbleContainer.transform = CGAffineTransformIdentity;
} completion:nil];
}
- (void)dismiss {
[UIView animateWithDuration:0.18f
delay:0.f
options:UIViewAnimationOptionCurveEaseIn
animations:^{
self.alpha = 0.f;
self.bubbleContainer.transform = CGAffineTransformMakeScale(0.85f, 0.85f);
} completion:^(BOOL finished) {
[self removeFromSuperview];
}];
}
#pragma mark - Private Actions
- (void)p_bubbleTapped {
//
}
#pragma mark - Lazy Load
- (_ABubbleContainerView *)bubbleContainer {
if (!_bubbleContainer) {
_bubbleContainer = [[_ABubbleContainerView alloc] init];
}
return _bubbleContainer;
}
- (UIView *)headerView {
if (!_headerView) {
_headerView = [[UIView alloc] init];
_headerView.backgroundColor = [UIColor hp_colorWithRGBHex:0x1BA855];
if (@available(iOS 11.0, *)) {
_headerView.layer.cornerRadius = kBubbleRadius;
_headerView.layer.maskedCorners = kCALayerMinXMinYCorner | kCALayerMaxXMinYCorner;
_headerView.clipsToBounds = YES;
}
}
return _headerView;
}
- (UILabel *)titleLabel {
if (!_titleLabel) {
_titleLabel = [[UILabel alloc] init];
_titleLabel.text = @"加氢规划模式";
_titleLabel.textColor = [UIColor whiteColor];
_titleLabel.font = [UIFont boldSystemFontOfSize:15.f];
_titleLabel.textAlignment = NSTextAlignmentCenter;
}
return _titleLabel;
}
- (UIView *)separatorLine1 {
if (!_separatorLine1) {
_separatorLine1 = [[UIView alloc] init];
_separatorLine1.backgroundColor = [UIColor colorWithWhite:0.88f alpha:1.f];
}
return _separatorLine1;
}
- (UILabel *)option1Label {
if (!_option1Label) {
_option1Label = [[UILabel alloc] init];
_option1Label.text = @"送货规划模式";
_option1Label.textColor = [UIColor hp_colorWithRGBHex:0xC9CDD4];
_option1Label.font = [UIFont boldSystemFontOfSize:14.f];
_option1Label.textAlignment = NSTextAlignmentCenter;
}
return _option1Label;
}
- (UIView *)separatorLine2 {
if (!_separatorLine2) {
_separatorLine2 = [[UIView alloc] init];
_separatorLine2.backgroundColor = [UIColor colorWithWhite:0.88f alpha:1.f];
}
return _separatorLine2;
}
- (UILabel *)option2Label {
if (!_option2Label) {
_option2Label = [[UILabel alloc] init];
_option2Label.text = @"成本计算模式";
_option2Label.textColor = [UIColor hp_colorWithRGBHex:0xC9CDD4];
_option2Label.font = [UIFont boldSystemFontOfSize:14.f];
_option2Label.textAlignment = NSTextAlignmentCenter;
}
return _option2Label;
}
@end

View File

@@ -0,0 +1,16 @@
//
// ACustomNaviDriveController.h
// AMapNavIOSSDK
//
// Created by admin on 2026/4/11.
//
#import "ABaseViewController.h"
NS_ASSUME_NONNULL_BEGIN
@interface ACustomNaviDriveController : ABaseViewController
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,22 @@
//
// ACustomNaviDriveController.m
// AMapNavIOSSDK
//
// Created by admin on 2026/4/11.
//
#import "ACustomNaviDriveController.h"
@interface ACustomNaviDriveController ()
@end
@implementation ACustomNaviDriveController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
@end

View File

@@ -27,23 +27,15 @@
#pragma mark - url #pragma mark - url
///获取站点列表 ///获取站点列表
#define kGetStationListUrl @"https://beta-esg.api.lnh2e.com/appointment/station/getNearbyHydrogenStationsByLocation" #define kGetStationListUrl @"http://47.101.201.13:8443/api/appointment/station/getNearbyHydrogenStationsByLocation"
///单个站点详情 ///单个站点详情
#define kGetStationDetailtUrl @"https://beta-esg.api.lnh2e.com/appointment/station/getStationInfoByArea" #define kGetStationDetailtUrl @"http://47.101.201.13:8443/api/appointment/station/getStationInfoByArea"
///获取途经点 ///获取途经点
/**
请求方式post 暂时调不通
{
   "longitude":"121.254139",
    "latitude":"31.214628",
    "plateNumber":"浙F32111F",
"hydrogenSiteId":""//加氢站DI }
*/ #define kGetRoutePointtUrl @"http://47.101.201.13:8443/api/appointment/truck/truckRouteAlgorithm"
#define kGetRoutePointtUrl @"https://beta-esg.api.lnh2e.com/appointment/truck/truckRouteAlgorithm"
#import "ANavPointModel.h" #import "ANavPointModel.h"

View File

@@ -21,8 +21,8 @@
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@interface ARoutePlaneController : ABaseViewController @interface ARoutePlaneController : ABaseViewController<AMapNaviDriveDataRepresentable>
@property (nonatomic , strong) AMapNaviDriveView * driveView;
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

View File

@@ -18,7 +18,7 @@
#import "AMapPrivacyUtility.h" #import "AMapPrivacyUtility.h"
#import "AStationDetailPopupController.h" #import "AStationDetailPopupView.h"
#define kRouteIndicatorViewHeight 64.f #define kRouteIndicatorViewHeight 64.f
@@ -26,8 +26,9 @@
#import "AMapNavHttpUtil.h" #import "AMapNavHttpUtil.h"
#import "ACustomStepView.h" #import "ACustomStepView.h"
#import "ABottomBarView.h" #import "ABottomBarView.h"
#import "AAddHPopView.h"
@interface ARoutePlaneController ()<MAMapViewDelegate, AMapNaviDriveManagerDelegate,AMapNaviCompositeManagerDelegate , AMapLocationManagerDelegate , UITextFieldDelegate , AStationDetailPopupDelegate, ABottomBarViewDelegate> @interface ARoutePlaneController ()<MAMapViewDelegate, AMapNaviDriveManagerDelegate,AMapNaviCompositeManagerDelegate , AMapLocationManagerDelegate , UITextFieldDelegate , AStationDetailPopupViewDelegate, ABottomBarViewDelegate>
@property (nonatomic, strong) UITextField *textField; @property (nonatomic, strong) UITextField *textField;
/// +线 /// +线
@@ -65,11 +66,16 @@
@property (nonatomic , strong)ACustomStepView * stepView; @property (nonatomic , strong)ACustomStepView * stepView;
/// ///
@property (nonatomic , strong)AStationDetailPopupController * stationDetailPopup; @property (nonatomic , strong)AStationDetailPopupView * stationDetailPopup;
@property (nonatomic, strong) ANavPointModel *pointModel; // @property (nonatomic, strong) ANavPointModel *pointModel; //
@property (nonatomic, strong) ATripCalcDataModel * tjdPathInfoModel;// @property (nonatomic, strong) ATripCalcDataModel * tjdPathInfoModel;//
@property (nonatomic, strong) CLLocationManager * locationManager; @property (nonatomic, strong) CLLocationManager * locationManager;
///
@property (nonatomic, weak) UIButton *addHBtn;
@property (nonatomic ,strong)MAAnnotationView * currAnnotionView;
@end @end
@implementation ARoutePlaneController @implementation ARoutePlaneController
@@ -156,6 +162,8 @@
-(void)requestRoutePathWithParms:(NSDictionary*)dic completeHandle:(void(^)(ATripCalcDataModel * tjd))blk { -(void)requestRoutePathWithParms:(NSDictionary*)dic completeHandle:(void(^)(ATripCalcDataModel * tjd))blk {
///
self.tjdPathInfoModel = nil;
NSString * token = [[NSUserDefaults standardUserDefaults]valueForKey:@"flutter.token"]; NSString * token = [[NSUserDefaults standardUserDefaults]valueForKey:@"flutter.token"];
NSString * carNo = [[NSUserDefaults standardUserDefaults]valueForKey:@"flutter.plateNumber"]; NSString * carNo = [[NSUserDefaults standardUserDefaults]valueForKey:@"flutter.plateNumber"];
@@ -168,11 +176,14 @@
} }
NSMutableDictionary * dic2 = [NSMutableDictionary dictionary]; NSMutableDictionary * dic2 = [NSMutableDictionary dictionary];
dic2[@"longitude"] = [NSString stringWithFormat:@"%f" , self.pointModel.coordinate.longitude]; dic2[@"longitude"] = [NSString stringWithFormat:@"%f" , self.longitude];
dic2[@"latitude"] = [NSString stringWithFormat:@"%f" , self.pointModel.coordinate.latitude]; dic2[@"latitude"] = [NSString stringWithFormat:@"%f" , self.latitude];
dic2[@"plateNumber"] = carNo; dic2[@"plateNumber"] = carNo;
dic2[@"hydrogenSiteId"] = [NSString stringWithFormat:@"%@" , self.pointModel.stationID]; dic2[@"hydrogenSiteId"] = [NSString stringWithFormat:@"%@" , self.pointModel.stationID];
NSLog(@"🔍 Route API Request Params: %@", dic2);
NSLog(@"🔍 Request URL: %@", kGetRoutePointtUrl);
NSDictionary * headDic = @{ NSDictionary * headDic = @{
@"Content-Type":@"application/json; charset=UTF-8", @"Content-Type":@"application/json; charset=UTF-8",
@"asoco-token" : token @"asoco-token" : token
@@ -185,9 +196,16 @@
NSString * url = kGetRoutePointtUrl; NSString * url = kGetRoutePointtUrl;
[AMapNavHttpUtil postRequestWithURL:url parameters:dic2 requestHeader:headDic successHandler:^(NSDictionary * _Nonnull data, NSURLResponse * _Nonnull response) { [AMapNavHttpUtil postRequestWithURL:url parameters:dic2 requestHeader:headDic successHandler:^(NSDictionary * _Nonnull data, NSURLResponse * _Nonnull response) {
NSLog(@"🔍 Route API Response: %@", data);
ATripCalcResponse * resp = [ATripCalcResponse mj_objectWithKeyValues:data]; ATripCalcResponse * resp = [ATripCalcResponse mj_objectWithKeyValues:data];
NSLog(@"🔍 Parsed resp.code: %ld", (long)resp.code);
NSLog(@"🔍 Parsed resp.data: %@", resp.data);
if (resp.code == 200 && resp.data) { if (resp.code == 200 && resp.data) {
self.tjdPathInfoModel = resp.data; self.tjdPathInfoModel = resp.data;
NSLog(@"🔍 Parsed algorithmPath: %@", self.tjdPathInfoModel.algorithmPath);
NSLog(@"🔍 Parsed hydrogenCost: %@", self.tjdPathInfoModel.algorithmPath.hydrogenCost);
if (blk) { if (blk) {
blk(resp.data); blk(resp.data);
@@ -279,7 +297,8 @@
[bottomBar mas_makeConstraints:^(MASConstraintMaker *make) { [bottomBar mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.equalTo(self.view); make.left.right.equalTo(self.view);
make.bottom.equalTo(self.view); // make.bottom.equalTo(self.view).offset(-AMP_TabbarHeight - 13);
make.bottom.equalTo(self.view).offset(0);
}]; }];
// startTf / dstTf // startTf / dstTf
@@ -319,25 +338,55 @@
[stepView addObserver:self forKeyPath:@"value" options:NSKeyValueObservingOptionNew context:nil]; [stepView addObserver:self forKeyPath:@"value" options:NSKeyValueObservingOptionNew context:nil];
self.stepView = stepView; self.stepView = stepView;
stepView.hidden = YES;
/// ///
UIButton * btn = [UIButton buttonWithType:UIButtonTypeCustom]; UIButton * btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn setImage:[AMapNavCommonUtil imageWithName3x:@"my_location_icon"] forState:UIControlStateNormal]; [btn setBackgroundImage:[AMapNavCommonUtil imageWithName3x:@"my_location_icon"] forState:UIControlStateNormal];
btn.backgroundColor = [UIColor lightGrayColor];
btn.backgroundColor = [UIColor whiteColor];
btn.titleLabel.font = [UIFont systemFontOfSize:14]; btn.titleLabel.font = [UIFont systemFontOfSize:14];
btn.layer.cornerRadius = 20; btn.layer.cornerRadius = 22;
[btn addTarget:self action:@selector(updateUserLocalAction) forControlEvents:UIControlEventTouchUpInside]; [btn addTarget:self action:@selector(updateUserLocalAction) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn]; [self.view addSubview:btn];
[btn mas_makeConstraints:^(MASConstraintMaker *make) { [btn mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.equalTo(self.view).offset(-10); make.right.equalTo(self.view).offset(-10);
make.width.height.equalTo(@40); make.width.height.equalTo(@44);
make.bottom.equalTo(bottomBar.mas_top).offset(-85); make.bottom.equalTo(bottomBar.mas_top).offset(-105);
}]; }];
///
UIButton *addHbtn = [UIButton buttonWithType:UIButtonTypeCustom];
addHbtn.backgroundColor = [UIColor hp_colorWithRGBHex:0x017137];
addHbtn.titleLabel.numberOfLines = 2;
[addHbtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[addHbtn setTitle:@"加氢规划" forState:UIControlStateNormal];
addHbtn.titleLabel.font = [UIFont boldSystemFontOfSize:11];
addHbtn.titleEdgeInsets = UIEdgeInsetsMake(0, 3, 0, 3);
addHbtn.layer.cornerRadius = 22;
[addHbtn addTarget:self action:@selector(addHbtnAction:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:addHbtn];
[addHbtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.equalTo(self.view).offset(-10);
make.width.height.equalTo(@44);
make.bottom.equalTo(btn.mas_top).offset(-25);
}];
self.addHBtn = addHbtn;
} }
- (void)addHbtnAction:(UIButton *)sender {
//
AAddHPopView *popView = [[AAddHPopView alloc] init];
[popView showInView:self.view sourceView:sender];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context { - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
if ([keyPath isEqualToString:@"value"]) { if ([keyPath isEqualToString:@"value"]) {
self.mapView.zoomLevel = [change[NSKeyValueChangeNewKey] doubleValue]; self.mapView.zoomLevel = [change[NSKeyValueChangeNewKey] doubleValue];
@@ -363,6 +412,7 @@
self.mapView.userTrackingMode = MAUserTrackingModeFollowWithHeading; self.mapView.userTrackingMode = MAUserTrackingModeFollowWithHeading;
self.mapView.desiredAccuracy = kCLLocationAccuracyNearestTenMeters; // self.mapView.desiredAccuracy = kCLLocationAccuracyNearestTenMeters; //
_mapView.showsScale= YES; _mapView.showsScale= YES;
_mapView.showsCompass = NO;
_mapView.logoCenter = CGPointMake(CGRectGetWidth(self.view.bounds)-55, 450); _mapView.logoCenter = CGPointMake(CGRectGetWidth(self.view.bounds)-55, 450);
self.mapView.zoomLevel = 11; self.mapView.zoomLevel = 11;
@@ -389,7 +439,7 @@
CLLocationCoordinate2D coord = CLLocationCoordinate2DMake(self.latitude, self.longitude); CLLocationCoordinate2D coord = CLLocationCoordinate2DMake(self.latitude, self.longitude);
[_mapView setCenterCoordinate:coord animated:YES]; [_mapView setCenterCoordinate:coord animated:YES];
// [_mapView setZoomLevel:10 animated:YES]; [_mapView setZoomLevel:15.0 animated:YES];
} else { } else {
// //
[_mapView setUserTrackingMode:MAUserTrackingModeFollow animated:YES]; [_mapView setUserTrackingMode:MAUserTrackingModeFollow animated:YES];
@@ -508,7 +558,7 @@
0, 0,
0, 0,
0); 0);
strategy = AMapNaviDrivingStrategyMultipleDefault;//使 strategy = AMapNaviDrivingStrategyMultipleDefault;//使DRIVING_MULTIPLE_ROUTES_DEFAULT
id delegate = [AMapNaviDriveManager sharedInstance].delegate; id delegate = [AMapNaviDriveManager sharedInstance].delegate;
if (!delegate) { if (!delegate) {
@@ -780,6 +830,7 @@
[config setNeedCalculateRouteWhenPresent:NO];// [config setNeedCalculateRouteWhenPresent:NO];//
[config setMultipleRouteNaviMode:NO];//线 [config setMultipleRouteNaviMode:NO];//线
// [config setNeedDestoryDriveManagerInstanceWhenDismiss:NO]; // [config setNeedDestoryDriveManagerInstanceWhenDismiss:NO];
[config setShowDrivingStrategyPreferenceView:NO];
[self.compositeManager presentRoutePlanViewControllerWithOptions:config]; [self.compositeManager presentRoutePlanViewControllerWithOptions:config];
} }
@@ -797,6 +848,8 @@
// [config setMultipleRouteNaviMode:NO];//线 // [config setMultipleRouteNaviMode:NO];//线
// [config setNeedDestoryDriveManagerInstanceWhenDismiss:NO]; // [config setNeedDestoryDriveManagerInstanceWhenDismiss:NO];
// [config setShowDrivingStrategyPreferenceView:NO];
[self.compositeManager presentRoutePlanViewControllerWithOptions:config]; [self.compositeManager presentRoutePlanViewControllerWithOptions:config];
} }
@@ -978,6 +1031,7 @@
} }
- (void)mapView:(MAMapView *)mapView didSelectAnnotationView:(MAAnnotationView *)view { - (void)mapView:(MAMapView *)mapView didSelectAnnotationView:(MAAnnotationView *)view {
self.currAnnotionView = view;
id pointAnnotation = view.annotation; id pointAnnotation = view.annotation;
if ([pointAnnotation isMemberOfClass:ACustomPointAnnotation.class]) { if ([pointAnnotation isMemberOfClass:ACustomPointAnnotation.class]) {
@@ -995,9 +1049,13 @@
[self updateUIWithData:aoi textField:self.dstTf]; [self updateUIWithData:aoi textField:self.dstTf];
///
//
[self willRequestTJDInfo];
// //
self.bottomBarView.destinationText = aoi.name; // self.bottomBarView.destinationText = aoi.name;
self.bottomBarView.destinationText = nil;
} }
} }
@@ -1009,6 +1067,7 @@
self.dstPoi = nil; self.dstPoi = nil;
self.dstTf.text = nil; self.dstTf.text = nil;
self.bottomBarView.destinationText = nil; self.bottomBarView.destinationText = nil;
self.currAnnotionView = nil;
} }
} }
@@ -1056,6 +1115,7 @@
AMapPOI *_dstPoi = self.dstPoi ? self.dstPoi : self.defaultDstPoi; AMapPOI *_dstPoi = self.dstPoi ? self.dstPoi : self.defaultDstPoi;
if (!_dstPoi) { if (!_dstPoi) {
[AMapNavCommonUtil showMsg:@"请先选择目的地"];
return; return;
} }
@@ -1066,9 +1126,19 @@
navPoint.stationID = _dstPoi.uid; navPoint.stationID = _dstPoi.uid;
self.pointModel = navPoint; self.pointModel = navPoint;
if (self.stationDetailPopup) {
[self.stationDetailPopup resetUI];
}
///_stationID 线 ///_stationID 线
if (!navPoint.stationID) { if (!navPoint.stationID) {
[self gd_calPathWithNoStationId:navPoint]; // [self gd_calPathWithNoStationId:navPoint];
ANavPointModel * model = [ANavPointModel new];
model.name = navPoint.name;
model.address = navPoint.address;
[self showDstInfoPop:model];
return; return;
}else { }else {
__weak typeof(self) weakSelf = self; __weak typeof(self) weakSelf = self;
@@ -1084,7 +1154,7 @@
// --- --- // --- ---
if (!self.stationDetailPopup) { if (!self.stationDetailPopup) {
AStationDetailPopupController *popup = [[AStationDetailPopupController alloc] init]; AStationDetailPopupView *popup = [[AStationDetailPopupView alloc] init];
popup.delegate = self; popup.delegate = self;
self.stationDetailPopup = popup; self.stationDetailPopup = popup;
} }
@@ -1092,6 +1162,8 @@
self.stationDetailPopup.pointModel = navPoint; self.stationDetailPopup.pointModel = navPoint;
/// ///
NSLog(@"🔍 Debug algorithmPath: %@", self.tjdPathInfoModel.algorithmPath);
NSLog(@"🔍 Debug hydrogenCost: %@", self.tjdPathInfoModel.algorithmPath.hydrogenCost);
self.stationDetailPopup.estimatedCost = self.tjdPathInfoModel.algorithmPath.hydrogenCost; self.stationDetailPopup.estimatedCost = self.tjdPathInfoModel.algorithmPath.hydrogenCost;
/// ///
self.stationDetailPopup.estimatedTime = [NSString stringWithFormat:@"%.f" , self.tjdPathInfoModel.pathDto.duration / 60.0]; self.stationDetailPopup.estimatedTime = [NSString stringWithFormat:@"%.f" , self.tjdPathInfoModel.pathDto.duration / 60.0];
@@ -1101,13 +1173,25 @@
/// ///
self.stationDetailPopup.tollFee = self.tjdPathInfoModel.pathDto.tolls; self.stationDetailPopup.tollFee = self.tjdPathInfoModel.pathDto.tolls;
[self.stationDetailPopup presentInViewController:self]; ///
self.stationDetailPopup.contactName = self.tjdPathInfoModel.destinationSite.liaisonName;
self.stationDetailPopup.contactPhone = self.tjdPathInfoModel.destinationSite.liaisonPhone;
self.stationDetailPopup.businessHours = [NSString stringWithFormat:@"%@-%@" , [AMapNavCommonUtil stringValueFromStr:self.tjdPathInfoModel.destinationSite.startBusiness] , [AMapNavCommonUtil stringValueFromStr:self.tjdPathInfoModel.destinationSite.endBusiness]];
self.stationDetailPopup.hydrogenPrice = [AMapNavCommonUtil stringValueFromStr:self.tjdPathInfoModel.destinationSite.hydrogenPrice];
[self.stationDetailPopup showInView:self.view];
// [self addChildViewController:self.stationDetailPopup];
//
// CGRect rect = CGRectMake(CGRectGetMinX(self.view.frame), CGRectGetMinY(self.view.frame), CGRectGetWidth(self.view.frame), CGRectGetHeight(self.view.frame) - (AMP_TabbarHeight + 20) * 2);
// self.stationDetailPopup.view.frame = rect;
//
// [self.view addSubview:self.stationDetailPopup.view];
} }
#pragma mark - AStationDetailPopupDelegate #pragma mark - AStationDetailPopupViewDelegate
- (void)stationDetailPopupDidTapStartNavi:(AStationDetailPopupController *)popup { - (void)stationDetailPopupViewDidTapStartNavi:(AStationDetailPopupView *)popup {
self.stationDetailPopup = nil; self.stationDetailPopup = nil;
/// ///
///1线 ///1线
@@ -1126,13 +1210,17 @@
} }
} }
- (void)stationDetailPopupDidTapClose:(AStationDetailPopupController *)popup { - (void)stationDetailPopupViewDidTapClose:(AStationDetailPopupView *)popup {
self.stationDetailPopup = nil; self.stationDetailPopup = nil;
} }
#pragma mark - ABottomBarViewDelegate #pragma mark - ABottomBarViewDelegate
- (void)bottomBarViewDidTapCalRoute:(ABottomBarView *)barView { - (void)bottomBarViewDidTapCalRoute:(ABottomBarView *)barView {
if (self.currAnnotionView) {
[self.mapView deselectAnnotation:self.currAnnotionView.annotation animated:NO];
self.currAnnotionView = nil;
}
// //
[self willRequestTJDInfo]; [self willRequestTJDInfo];
@@ -1140,6 +1228,14 @@
} }
- (void)bottomBarViewDidTapSearchField:(ABottomBarView *)barView { - (void)bottomBarViewDidTapSearchField:(ABottomBarView *)barView {
///
self.tjdPathInfoModel = nil;
if (self.currAnnotionView) {
[self.mapView deselectAnnotation:self.currAnnotionView.annotation animated:NO];
self.currAnnotionView = nil;
}
// //
ASearchAddressController *vc = [[ASearchAddressController alloc] init]; ASearchAddressController *vc = [[ASearchAddressController alloc] init];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc]; UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
@@ -1160,7 +1256,8 @@
-(void)updateUIWithData: (AMapPOI*)poi textField: (UITextField*)tf { -(void)updateUIWithData: (AMapPOI*)poi textField: (UITextField*)tf {
BOOL isStart = tf.tag == 100; BOOL isStart = tf.tag == 100;
tf.text = poi.name; ///
// tf.text = poi.name;
if (isStart) { if (isStart) {
self.startPoi = poi; self.startPoi = poi;

View File

@@ -18,10 +18,12 @@
@property (nonatomic , strong) UIBarButtonItem *rightItem; @property (nonatomic , strong) UIBarButtonItem *rightItem;
@property (nonatomic ,strong)UIButton * backBtn; @property (nonatomic ,strong)UIButton * backBtn;
@property (nonatomic , strong) NSArray *dataArr; @property (nonatomic , strong) NSMutableArray *dataArr;
@property (nonatomic, strong) UITextField *inputAddressTf; @property (nonatomic, strong) UITextField *inputAddressTf;
@property (nonatomic, strong) AMapSearchAPI *search; @property (nonatomic, strong) AMapSearchAPI *search;
@property (nonatomic,assign)NSInteger currPage;
@end @end
@implementation ASearchAddressController @implementation ASearchAddressController
@@ -30,6 +32,9 @@
[super viewDidLoad]; [super viewDidLoad];
// Do any additional setup after loading the view. // Do any additional setup after loading the view.
self.title = @"选择地点"; self.title = @"选择地点";
self.currPage = 1;
_dataArr = [NSMutableArray array];
[self initSubview]; [self initSubview];
@@ -65,8 +70,9 @@
[inputAddressTf mas_makeConstraints:^(MASConstraintMaker *make) { [inputAddressTf mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(self.view).offset(10); make.left.mas_equalTo(self.view).offset(10);
make.right.mas_equalTo(self.view).offset(-10);
make.top.mas_equalTo(self.view).offset(kRoutePlanBarHeight + 10); make.top.mas_equalTo(self.view).offset(kRoutePlanBarHeight + 10);
make.height.mas_equalTo(@30); make.height.mas_equalTo(@35);
}]; }];
self.inputAddressTf = inputAddressTf; self.inputAddressTf = inputAddressTf;
@@ -80,6 +86,7 @@
btn.layer.borderWidth = 1; btn.layer.borderWidth = 1;
btn.layer.cornerRadius = 5; btn.layer.cornerRadius = 5;
btn.titleLabel.font = [UIFont systemFontOfSize:12]; btn.titleLabel.font = [UIFont systemFontOfSize:12];
btn.hidden = YES;
[btn setTitleColor:[UIColor blueColor] forState:UIControlStateNormal]; [btn setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
[btn addTarget:self action:@selector(searchBtnAction) forControlEvents:UIControlEventTouchUpInside]; [btn addTarget:self action:@selector(searchBtnAction) forControlEvents:UIControlEventTouchUpInside];
@@ -134,6 +141,14 @@
// [self.navigationController popViewControllerAnimated:YES]; // [self.navigationController popViewControllerAnimated:YES];
} }
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == self.dataArr.count - 1 && (self.dataArr.count % 20 == 0)) {
self.currPage = self.currPage + 1;
[self requestAddressWithAddress:self.inputAddressTf.text atPage:self.currPage];
}
}
#pragma mark - #pragma mark -
- (UITableView *)tableView { - (UITableView *)tableView {
if (!_tableView) { if (!_tableView) {
@@ -178,28 +193,32 @@
return; return;
} }
[self requestAddressWithAddress:addr atPage:1];
}
-(void)requestAddressWithAddress:(NSString *)addr atPage:(NSInteger)page {
AMapPOIKeywordsSearchRequest *request = [[AMapPOIKeywordsSearchRequest alloc] init]; AMapPOIKeywordsSearchRequest *request = [[AMapPOIKeywordsSearchRequest alloc] init];
request.keywords = addr; request.keywords = addr;
AMapNavSDKManager * sdk = [AMapNavSDKManager sharedManager]; AMapNavSDKManager * sdk = [AMapNavSDKManager sharedManager];
request.city = sdk.localCity; // request.city = sdk.localCity;
// request.types = @"高等院校"; // request.types = @"高等院校";
// request.requireExtension = YES; // request.requireExtension = YES;
request.offset =20; request.offset =20;
request.page = page;
/* SDK 3.2.0 POI*/ /* SDK 3.2.0 POI*/
request.cityLimit = YES; // request.cityLimit = YES;
// request.requireSubPOIs = YES; // request.requireSubPOIs = YES;
[self.search AMapPOIKeywordsSearch:request]; [self.search AMapPOIKeywordsSearch:request];
} }
#pragma mark - #pragma mark -
/* POI . */ /* POI . */
- (void)onPOISearchDone:(AMapPOISearchBaseRequest *)request response:(AMapPOISearchResponse *)response - (void)onPOISearchDone:(AMapPOISearchBaseRequest *)request response:(AMapPOISearchResponse *)response
@@ -212,7 +231,8 @@
//responsePOI Demo //responsePOI Demo
self.dataArr = [NSArray arrayWithArray:pois]; [self.dataArr addObjectsFromArray:pois];
[self.tableView reloadData]; [self.tableView reloadData];
} }
@@ -221,6 +241,8 @@
- (BOOL)textFieldShouldReturn:(UITextField *)textField { - (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder]; [textField resignFirstResponder];
[self.dataArr removeAllObjects];
self.currPage = 1;
[self startSearchWithAddress:textField.text]; [self startSearchWithAddress:textField.text];

View File

@@ -39,6 +39,19 @@ NS_ASSUME_NONNULL_BEGIN
/// 过路费,如 @"30元";若 nil 则隐藏 /// 过路费,如 @"30元";若 nil 则隐藏
@property (nonatomic, copy, nullable) NSString *tollFee; @property (nonatomic, copy, nullable) NSString *tollFee;
/// 营业时间,如 @"00:00-24:00";有值显示,无值显示 -
@property (nonatomic, copy, nullable) NSString *businessHours;
/// 站点联系人,如 @"陈凯";有值显示,无值显示 -
@property (nonatomic, copy, nullable) NSString *contactName;
/// 联系方式,如 @"18019187371";有值显示,无值显示 -
@property (nonatomic, copy, nullable) NSString *contactPhone;
/// 加氢价格,如 @"32元/L";有值显示,无值显示 -
@property (nonatomic, copy, nullable) NSString *hydrogenPrice;
@property (nonatomic, weak, nullable) id<AStationDetailPopupDelegate> delegate; @property (nonatomic, weak, nullable) id<AStationDetailPopupDelegate> delegate;
/// 以半透明蒙层方式弹出在目标控制器上 /// 以半透明蒙层方式弹出在目标控制器上
@@ -50,6 +63,9 @@ NS_ASSUME_NONNULL_BEGIN
/// 关闭弹框,动画结束后执行 completion用于关闭后再 present 其他页面) /// 关闭弹框,动画结束后执行 completion用于关闭后再 present 其他页面)
- (void)dismissWithCompletion:(nullable void(^)(void))completion; - (void)dismissWithCompletion:(nullable void(^)(void))completion;
-(void)resetUI;
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

View File

@@ -57,6 +57,21 @@ static inline UIColor *AStationThemeGreen(void) {
/// bottom constraint /// bottom constraint
@property (nonatomic, strong) MASConstraint *cardBottomConstraint; @property (nonatomic, strong) MASConstraint *cardBottomConstraint;
//
@property (nonatomic, strong) UILabel *businessHoursLabel;
//
@property (nonatomic, strong) UIImageView *contactPersonIconView;
@property (nonatomic, strong) UILabel *contactPersonLabel;
//
@property (nonatomic, strong) UIImageView *priceIconView;
@property (nonatomic, strong) UILabel *priceLabel;
//
@property (nonatomic, strong) UIImageView *phoneIconView;
@property (nonatomic, strong) UILabel *phoneLabel;
@end @end
@implementation AStationDetailPopupController @implementation AStationDetailPopupController
@@ -121,6 +136,26 @@ static inline UIColor *AStationThemeGreen(void) {
if (self.isViewLoaded) [self _updateUI]; if (self.isViewLoaded) [self _updateUI];
} }
- (void)setBusinessHours:(NSString *)businessHours {
_businessHours = [businessHours copy];
if (self.isViewLoaded) [self _updateUI];
}
- (void)setContactName:(NSString *)contactName {
_contactName = [contactName copy];
if (self.isViewLoaded) [self _updateUI];
}
- (void)setContactPhone:(NSString *)contactPhone {
_contactPhone = [contactPhone copy];
if (self.isViewLoaded) [self _updateUI];
}
- (void)setHydrogenPrice:(NSString *)hydrogenPrice {
_hydrogenPrice = [hydrogenPrice copy];
if (self.isViewLoaded) [self _updateUI];
}
#pragma mark - Build UI #pragma mark - Build UI
/** /**
@@ -168,10 +203,13 @@ static inline UIColor *AStationThemeGreen(void) {
[card addSubview:closeBtn]; [card addSubview:closeBtn];
self.closeButton = closeBtn; self.closeButton = closeBtn;
UIColor * headTextColor = [UIColor hp_colorWithRGBHex:0x1D2129];
UIFont * headTextFont = [UIFont hp_pingFangMedium:14];
// //
UILabel *nameLabel = [[UILabel alloc] init]; UILabel *nameLabel = [[UILabel alloc] init];
nameLabel.font = [UIFont boldSystemFontOfSize:18]; nameLabel.font = [UIFont hp_pingFangMedium:18];
nameLabel.textColor = [UIColor colorWithWhite:0.1 alpha:1]; nameLabel.textColor = headTextColor;
nameLabel.numberOfLines = 2; nameLabel.numberOfLines = 2;
// nameLabel.adjustsFontSizeToFitWidth = YES; // nameLabel.adjustsFontSizeToFitWidth = YES;
nameLabel.minimumScaleFactor = 0.8; nameLabel.minimumScaleFactor = 0.8;
@@ -180,8 +218,8 @@ static inline UIColor *AStationThemeGreen(void) {
// 20pt // 20pt
UILabel *costLabel = [[UILabel alloc] init]; UILabel *costLabel = [[UILabel alloc] init];
costLabel.font = [UIFont systemFontOfSize:14]; costLabel.font = headTextFont;
costLabel.textColor = [UIColor colorWithWhite:0.2 alpha:1]; costLabel.textColor = headTextColor;
costLabel.numberOfLines = 1; costLabel.numberOfLines = 1;
costLabel.textAlignment = NSTextAlignmentLeft; costLabel.textAlignment = NSTextAlignmentLeft;
// [costLabel setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal]; // [costLabel setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];
@@ -189,10 +227,18 @@ static inline UIColor *AStationThemeGreen(void) {
[card addSubview:costLabel]; [card addSubview:costLabel];
self.costLabel = costLabel; self.costLabel = costLabel;
// 4pt
UILabel *bizHoursLabel = [[UILabel alloc] init];
bizHoursLabel.font = [UIFont hp_pingFangRegular:14];
bizHoursLabel.textColor = [UIColor hp_colorWithRGBHex:0x1D2129];
bizHoursLabel.numberOfLines = 1;
[card addSubview:bizHoursLabel];
self.businessHoursLabel = bizHoursLabel;
// //
UILabel *addrLabel = [[UILabel alloc] init]; UILabel *addrLabel = [[UILabel alloc] init];
addrLabel.font = [UIFont systemFontOfSize:13]; addrLabel.font = [UIFont hp_pingFangRegular:14];
addrLabel.textColor = [UIColor colorWithWhite:0.5 alpha:1]; addrLabel.textColor = [UIColor hp_colorWithRGBHex:0x86909C];
addrLabel.numberOfLines = 2; addrLabel.numberOfLines = 2;
[card addSubview:addrLabel]; [card addSubview:addrLabel];
self.addressLabel = addrLabel; self.addressLabel = addrLabel;
@@ -212,45 +258,84 @@ static inline UIColor *AStationThemeGreen(void) {
// //
UIImageView *timeIcon = [[UIImageView alloc] init]; UIImageView *timeIcon = [[UIImageView alloc] init];
timeIcon.contentMode = UIViewContentModeScaleAspectFit; timeIcon.contentMode = UIViewContentModeScaleAspectFit;
timeIcon.image = [AMapNavCommonUtil imageWithName3x:@"pre_time_icon"]; timeIcon.image = [AMapNavCommonUtil imageWithName3x:@"ic_time"];
[card addSubview:timeIcon]; [card addSubview:timeIcon];
self.timeIconView = timeIcon; self.timeIconView = timeIcon;
// //
UILabel *timeLabel = [[UILabel alloc] init]; UILabel *timeLabel = [[UILabel alloc] init];
timeLabel.font = [UIFont systemFontOfSize:14]; timeLabel.font = headTextFont;
timeLabel.textColor = [UIColor colorWithWhite:0.2 alpha:1]; timeLabel.textColor = headTextColor;
[card addSubview:timeLabel]; [card addSubview:timeLabel];
self.timeLabel = timeLabel; self.timeLabel = timeLabel;
// //
UIImageView *distIcon = [[UIImageView alloc] init]; UIImageView *distIcon = [[UIImageView alloc] init];
distIcon.contentMode = UIViewContentModeScaleAspectFit; distIcon.contentMode = UIViewContentModeScaleAspectFit;
distIcon.image = [AMapNavCommonUtil imageWithName3x:@"pre_distance_icon"]; distIcon.image = [AMapNavCommonUtil imageWithName3x:@"ic_mileage"];
[card addSubview:distIcon]; [card addSubview:distIcon];
self.distanceIconView = distIcon; self.distanceIconView = distIcon;
// //
UILabel *distLabel = [[UILabel alloc] init]; UILabel *distLabel = [[UILabel alloc] init];
distLabel.font = [UIFont systemFontOfSize:14]; distLabel.font = headTextFont;
distLabel.textColor = [UIColor colorWithWhite:0.2 alpha:1]; distLabel.textColor = headTextColor;
[card addSubview:distLabel]; [card addSubview:distLabel];
self.distanceLabel = distLabel; self.distanceLabel = distLabel;
// //
UIImageView *tollIcon = [[UIImageView alloc] init]; UIImageView *tollIcon = [[UIImageView alloc] init];
tollIcon.contentMode = UIViewContentModeScaleAspectFit; tollIcon.contentMode = UIViewContentModeScaleAspectFit;
tollIcon.image = [AMapNavCommonUtil imageWithName3x:@"pre_cost_icon"]; tollIcon.image = [AMapNavCommonUtil imageWithName3x:@"ic_toll"];
[card addSubview:tollIcon]; [card addSubview:tollIcon];
self.tollIconView = tollIcon; self.tollIconView = tollIcon;
// //
UILabel *tollLabel = [[UILabel alloc] init]; UILabel *tollLabel = [[UILabel alloc] init];
tollLabel.font = [UIFont systemFontOfSize:14]; tollLabel.font = headTextFont;
tollLabel.textColor = [UIColor colorWithWhite:0.2 alpha:1]; tollLabel.textColor = headTextColor;
[card addSubview:tollLabel]; [card addSubview:tollLabel];
self.tollLabel = tollLabel; self.tollLabel = tollLabel;
// &
UIImageView *personIcon = [[UIImageView alloc] init];
personIcon.contentMode = UIViewContentModeScaleAspectFit;
personIcon.image = [AMapNavCommonUtil imageWithName3x:@"ic_person"];
[card addSubview:personIcon];
self.contactPersonIconView = personIcon;
UILabel *personLabel = [[UILabel alloc] init];
personLabel.font = headTextFont;
personLabel.textColor = headTextColor;
[card addSubview:personLabel];
self.contactPersonLabel = personLabel;
// &
UIImageView *priceIcon = [[UIImageView alloc] init];
priceIcon.contentMode = UIViewContentModeScaleAspectFit;
priceIcon.image = [AMapNavCommonUtil imageWithName3x:@"ic_price"];
[card addSubview:priceIcon];
self.priceIconView = priceIcon;
UILabel *priceLabel = [[UILabel alloc] init];
priceLabel.font = headTextFont;
priceLabel.textColor = headTextColor;
[card addSubview:priceLabel];
self.priceLabel = priceLabel;
// &
UIImageView *phoneIcon = [[UIImageView alloc] init];
phoneIcon.contentMode = UIViewContentModeScaleAspectFit;
phoneIcon.image = [AMapNavCommonUtil imageWithName3x:@"ic_phone"];
[card addSubview:phoneIcon];
self.phoneIconView = phoneIcon;
UILabel *phoneLabel = [[UILabel alloc] init];
phoneLabel.font = headTextFont;
phoneLabel.textColor = headTextColor;
[card addSubview:phoneLabel];
self.phoneLabel = phoneLabel;
// //
UIButton *naviBtn = [UIButton buttonWithType:UIButtonTypeCustom]; UIButton *naviBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[naviBtn setTitle:@"开始导航" forState:UIControlStateNormal]; [naviBtn setTitle:@"开始导航" forState:UIControlStateNormal];
@@ -301,24 +386,34 @@ static inline UIColor *AStationThemeGreen(void) {
make.right.equalTo(self.closeButton.mas_left).offset(-12); make.right.equalTo(self.closeButton.mas_left).offset(-12);
}]; }];
// 6pt // 6pt
[self.addressLabel mas_makeConstraints:^(MASConstraintMaker *make) { [self.businessHoursLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.stationNameLabel.mas_bottom).offset(10); make.top.equalTo(self.stationNameLabel.mas_bottom).offset(10);
make.left.equalTo(card).offset(16); make.left.equalTo(card).offset(16);
make.right.equalTo(card).offset(-16); make.right.equalTo(card).offset(-16);
}]; }];
// 6pt
[self.addressLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.businessHoursLabel.mas_bottom).offset(10);
make.left.equalTo(card).offset(16);
make.right.equalTo(card).offset(-16);
}];
self.separator.hidden = YES;
// 线12pt // 线12pt
[self.separator mas_makeConstraints:^(MASConstraintMaker *make) { [self.separator mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.addressLabel.mas_bottom).offset(15); make.top.equalTo(self.addressLabel.mas_bottom).offset(10);
make.left.equalTo(card).offset(16); make.left.equalTo(card).offset(16);
make.right.equalTo(card).offset(-16); make.right.equalTo(card).offset(-16);
make.height.mas_equalTo(0.5); make.height.mas_equalTo(0.5);
}]; }];
CGFloat _offset_y = 18;
// 线14pt // 线14pt
[self.timeIconView mas_makeConstraints:^(MASConstraintMaker *make) { [self.timeIconView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.separator.mas_bottom).offset(15); make.top.equalTo(self.separator.mas_bottom).offset(12);
make.left.equalTo(card).offset(16); make.left.equalTo(card).offset(16);
make.width.height.mas_equalTo(iconSize); make.width.height.mas_equalTo(iconSize);
}]; }];
@@ -333,7 +428,7 @@ static inline UIColor *AStationThemeGreen(void) {
///cost ///cost
[self.costIconView mas_makeConstraints:^(MASConstraintMaker *make) { [self.costIconView mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(self.timeIconView); make.centerY.equalTo(self.timeIconView);
make.left.equalTo(self.timeLabel.mas_right).offset(30); make.left.equalTo(self.timeLabel.mas_right).offset(40);
make.width.height.mas_equalTo(iconSize); make.width.height.mas_equalTo(iconSize);
}]; }];
@@ -346,7 +441,7 @@ static inline UIColor *AStationThemeGreen(void) {
// + 12pt // + 12pt
[self.distanceIconView mas_makeConstraints:^(MASConstraintMaker *make) { [self.distanceIconView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.timeIconView.mas_bottom).offset(15); make.top.equalTo(self.timeIconView.mas_bottom).offset(_offset_y);
make.left.equalTo(card).offset(16); make.left.equalTo(card).offset(16);
make.width.height.mas_equalTo(iconSize); make.width.height.mas_equalTo(iconSize);
}]; }];
@@ -372,9 +467,49 @@ static inline UIColor *AStationThemeGreen(void) {
make.height.mas_equalTo(24); make.height.mas_equalTo(24);
}]; }];
// 18pt30pt // 14pt
[self.contactPersonIconView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.distanceIconView.mas_bottom).offset(_offset_y);
make.left.equalTo(card).offset(16);
make.width.height.mas_equalTo(iconSize);
}];
[self.contactPersonLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(self.contactPersonIconView);
make.left.equalTo(self.contactPersonIconView.mas_right).offset(6);
make.height.mas_equalTo(24);
}];
// costIconView
[self.priceIconView mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(self.contactPersonIconView);
make.left.equalTo(self.costIconView.mas_left);
make.width.height.mas_equalTo(iconSize);
}];
[self.priceLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(self.contactPersonIconView);
make.left.equalTo(self.priceIconView.mas_right).offset(6);
make.right.lessThanOrEqualTo(card).offset(-10);
make.height.mas_equalTo(24);
}];
// 12pt
[self.phoneIconView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.contactPersonIconView.mas_bottom).offset(_offset_y);
make.left.equalTo(card).offset(16);
make.width.height.mas_equalTo(iconSize);
}];
[self.phoneLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(self.phoneIconView);
make.left.equalTo(self.phoneIconView.mas_right).offset(6);
make.height.mas_equalTo(24);
}];
// 18pt safeArea
[self.startNaviButton mas_makeConstraints:^(MASConstraintMaker *make) { [self.startNaviButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.distanceIconView.mas_bottom).offset(50); make.top.equalTo(self.phoneIconView.mas_bottom).offset(40);
make.left.equalTo(card).offset(16); make.left.equalTo(card).offset(16);
make.right.equalTo(card).offset(-16); make.right.equalTo(card).offset(-16);
make.height.mas_equalTo(48); make.height.mas_equalTo(48);
@@ -386,29 +521,63 @@ static inline UIColor *AStationThemeGreen(void) {
- (void)_updateUI { - (void)_updateUI {
self.stationNameLabel.text = (self.pointModel.name.length > 0) self.stationNameLabel.text = (self.pointModel.name.length > 0)
? self.pointModel.name : @"--"; ? self.pointModel.name : @"-";
//
self.businessHoursLabel.text = (self.businessHours.length > 0)
? [NSString stringWithFormat:@"营业时间:%@", self.businessHours]
: @"营业时间:-";
self.costLabel.text = (self.estimatedCost.length > 0) self.costLabel.text = (self.estimatedCost.length > 0)
? [NSString stringWithFormat:@"预计加氢费用:%@元", self.estimatedCost] ? [NSString stringWithFormat:@"预计加氢费用:%@元", self.estimatedCost]
: @"预计加氢费用:--元"; : @"预计加氢费用:-";
self.addressLabel.text = (self.pointModel.address.length > 0) self.addressLabel.text = (self.pointModel.address.length > 0)
? self.pointModel.address : @"--"; ? self.pointModel.address : @"-";
// "-- 分钟" // "-- 分钟"
self.timeLabel.text = (self.estimatedTime.length > 0) self.timeLabel.text = (self.estimatedTime.length > 0)
? [NSString stringWithFormat:@"预计时间:%@分钟", self.estimatedTime] ? [NSString stringWithFormat:@"预计时间:%@分钟", self.estimatedTime]
: @"预计时间:--分钟"; : @"预计时间:-";
// "-- 公里" // "-- 公里"
self.distanceLabel.text = (self.driveDistance.length > 0) self.distanceLabel.text = (self.driveDistance.length > 0)
? [NSString stringWithFormat:@"行驶里程:%@公里", self.driveDistance] ? [NSString stringWithFormat:@"行驶里程:%@公里", self.driveDistance]
: @"行驶里程:--公里"; : @"行驶里程:-";
// "-- 元" // "-- 元"
self.tollLabel.text = (self.tollFee.length > 0) self.tollLabel.text = (self.tollFee.length > 0)
? [NSString stringWithFormat:@"过路费:%@元", self.tollFee] ? [NSString stringWithFormat:@"过路费:%@元", self.tollFee]
: @"过路费:--元"; : @"过路费:-";
// -
self.contactPersonLabel.text = (self.contactName.length > 0)
? [NSString stringWithFormat:@"站联系人:%@", self.contactName]
: @"站联系人:-";
// -
self.priceLabel.text = (self.hydrogenPrice.length > 0)
? [NSString stringWithFormat:@"加氢价格:%@/L", self.hydrogenPrice]
: @"加氢价格:-";
// -
self.phoneLabel.text = (self.contactPhone.length > 0)
? [NSString stringWithFormat:@"联系方式:%@", self.contactPhone]
: @"联系方式:-";
}
// UI
-(void)resetUI {
self.stationNameLabel.text = @"-";
self.businessHoursLabel.text = @"营业时间:-";
self.costLabel.text = @"预计加氢费用:-";
self.addressLabel.text = @"地址:-";
self.timeLabel.text = @"预计时间:-";
self.distanceLabel.text = @"行驶里程:-";
self.tollLabel.text = @"过路费:-";
self.contactPersonLabel.text = @"站联系人:-";
self.priceLabel.text = @"加氢价格:-";
self.phoneLabel.text = @"联系方式:-";
} }
#pragma mark - Animation #pragma mark - Animation

View File

@@ -59,6 +59,11 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, copy, nullable) NSString *latitude; @property (nonatomic, copy, nullable) NSString *latitude;
@property (nonatomic, copy, nullable) NSString *distance; @property (nonatomic, copy, nullable) NSString *distance;
///新增弹框参数4.13
@property (nonatomic, copy, nullable) NSString *hydrogenPrice;
@property (nonatomic, copy, nullable) NSString *liaisonName;
@property (nonatomic, copy, nullable) NSString *liaisonPhone;
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

View File

@@ -7,6 +7,8 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
#import "UIColor+ANavMap.h"
#import "UIFont+HP.h"
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@@ -34,6 +36,8 @@ BOOL stringIsEmpty(NSString *str);
/// 判断字符串是否非空 /// 判断字符串是否非空
BOOL stringIsNotEmpty(NSString *str); BOOL stringIsNotEmpty(NSString *str);
+(NSString *)stringValueFromStr:(NSString *)str;
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

View File

@@ -117,6 +117,15 @@ BOOL stringIsNotEmpty (NSString *str)
return ! stringIsEmpty(str); return ! stringIsEmpty(str);
} }
///
+(NSString *)stringValueFromStr:(NSString *)str {
if (stringIsEmpty(str)) {
return @"";
}
return str;
}
#pragma mark - #pragma mark -
+(UIImage *)imageWithName:(NSString *)name { +(UIImage *)imageWithName:(NSString *)name {

View File

@@ -0,0 +1,20 @@
//
// UIColor+ANavMap.h
// AMapNavIOSSDK
//
// Created by admin on 2026/4/11.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface UIColor (ANavMap)
+ (UIColor *)hp_colorWithRGBHex:(UInt32)hex;
+ (UIColor *)hp_colorWithRGBHex:(UInt32)hex alpha:(CGFloat)alpha;
//格式AHEX
+ (UIColor *)hp_colorWithRGBAHEX:(UInt32)hex;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,53 @@
//
// UIColor+ANavMap.m
// AMapNavIOSSDK
//
// Created by admin on 2026/4/11.
//
#import "UIColor+ANavMap.h"
@implementation UIColor (ANavMap)
//HEX
+ (UIColor *)hp_colorWithRGBHex:(UInt32)hex
{
CGFloat r = (hex >> 16) & 0xFF;
CGFloat g = (hex >> 8) & 0xFF;
CGFloat b = (hex) & 0xFF;
CGFloat a = 1.0f;
return [UIColor colorWithRed:r / 255.0f
green:g / 255.0f
blue:b / 255.0f
alpha:a];
}
+ (UIColor *)hp_colorWithRGBHex:(UInt32)hex alpha:(CGFloat)alpha
{
CGFloat r = (hex >> 16) & 0xFF;
CGFloat g = (hex >> 8) & 0xFF;
CGFloat b = (hex) & 0xFF;
CGFloat a = alpha;
return [UIColor colorWithRed:r / 255.0f
green:g / 255.0f
blue:b / 255.0f
alpha:a];
}
//AHEX
+ (UIColor *)hp_colorWithRGBAHEX:(UInt32)hex
{
CGFloat r = (hex >> 24) & 0xFF;
CGFloat g = (hex >> 16) & 0xFF;
CGFloat b = (hex >> 8) & 0xFF;
CGFloat a = (hex) & 0xFF;
return [UIColor colorWithRed:r / 255.0f
green:g / 255.0f
blue:b / 255.0f
alpha:a / 255.0f];
}
@end

View File

@@ -0,0 +1,36 @@
//
// UIFont+HP.h
// Hippo
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
/**
* UIFont 快捷分类
* 统一使用 PingFang SC 字族,覆盖 Light / Regular / Medium / Semibold 四个字重。
*
* 使用示例:
* label.font = [UIFont hp_pingFangLight:14];
* label.font = [UIFont hp_pingFangRegular:16];
* label.font = [UIFont hp_pingFangMedium:15];
* label.font = [UIFont hp_pingFangSemibold:18];
*/
@interface UIFont (HP)
#pragma mark - PingFang SC Light细体
+ (UIFont *)hp_pingFangLight:(CGFloat)size;
#pragma mark - PingFang SC Regular常规
+ (UIFont *)hp_pingFangRegular:(CGFloat)size;
#pragma mark - PingFang SC Medium中等
+ (UIFont *)hp_pingFangMedium:(CGFloat)size;
#pragma mark - PingFang SC Semibold半粗
+ (UIFont *)hp_pingFangSemibold:(CGFloat)size;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,45 @@
//
// UIFont+HP.m
// Hippo
//
#import "UIFont+HP.h"
// PingFang SC
static NSString * const kHPFontPingFangLight = @"PingFangSC-Light";
static NSString * const kHPFontPingFangRegular = @"PingFangSC-Regular";
static NSString * const kHPFontPingFangMedium = @"PingFangSC-Medium";
static NSString * const kHPFontPingFangSemibold = @"PingFangSC-Semibold";
@implementation UIFont (HP)
#pragma mark - PingFang SC Light
+ (UIFont *)hp_pingFangLight:(CGFloat)size {
UIFont *font = [UIFont fontWithName:kHPFontPingFangLight size:size];
// 退
return font ?: [UIFont systemFontOfSize:size weight:UIFontWeightLight];
}
#pragma mark - PingFang SC Regular
+ (UIFont *)hp_pingFangRegular:(CGFloat)size {
UIFont *font = [UIFont fontWithName:kHPFontPingFangRegular size:size];
return font ?: [UIFont systemFontOfSize:size weight:UIFontWeightRegular];
}
#pragma mark - PingFang SC Medium
+ (UIFont *)hp_pingFangMedium:(CGFloat)size {
UIFont *font = [UIFont fontWithName:kHPFontPingFangMedium size:size];
return font ?: [UIFont systemFontOfSize:size weight:UIFontWeightMedium];
}
#pragma mark - PingFang SC Semibold
+ (UIFont *)hp_pingFangSemibold:(CGFloat)size {
UIFont *font = [UIFont fontWithName:kHPFontPingFangSemibold size:size];
return font ?: [UIFont systemFontOfSize:size weight:UIFontWeightSemibold];
}
@end

View File

@@ -163,6 +163,7 @@ static inline UIColor *ABottomBarThemeGreen(void) {
self.calRouteButton = btn; self.calRouteButton = btn;
CGFloat off_y = AMP_TabbarHeight; CGFloat off_y = AMP_TabbarHeight;
off_y = 0;
#ifdef kAMapSDKDebugFlag #ifdef kAMapSDKDebugFlag
off_y = 0; off_y = 0;
#endif #endif
@@ -172,7 +173,7 @@ static inline UIColor *ABottomBarThemeGreen(void) {
make.left.equalTo(card).offset(16); make.left.equalTo(card).offset(16);
make.right.equalTo(card).offset(-16); make.right.equalTo(card).offset(-16);
make.height.mas_equalTo(48); make.height.mas_equalTo(48);
make.bottom.equalTo(card).offset(-40 - off_y); make.bottom.equalTo(card).offset(-40 + (-AMP_TabbarHeight - 13));
}]; }];
} }

View File

@@ -0,0 +1,70 @@
//
// AStationDetailPopupView.h
// AMapNavIOSSDK
//
// Created by admin on 2026/3/22.
//
#import <UIKit/UIKit.h>
#import "ANavPointModel.h"
#import "AMapNavSDKHeader.h"
NS_ASSUME_NONNULL_BEGIN
@class AStationDetailPopupView;
@protocol AStationDetailPopupViewDelegate <NSObject>
@optional
/// 点击"开始导航"
- (void)stationDetailPopupViewDidTapStartNavi:(AStationDetailPopupView *)popup;
/// 点击关闭
- (void)stationDetailPopupViewDidTapClose:(AStationDetailPopupView *)popup;
@end
@interface AStationDetailPopupView : UIView
@property (nonatomic, strong, nullable) ANavPointModel *pointModel;
/// 预计加氢费用(元),可由外部传入;若 nil 则隐藏
@property (nonatomic, copy, nullable) NSString *estimatedCost;
/// 预计时间,如 @"15分钟";若 nil 则隐藏
@property (nonatomic, copy, nullable) NSString *estimatedTime;
/// 行驶里程,如 @"23.5公里";若 nil 则隐藏
@property (nonatomic, copy, nullable) NSString *driveDistance;
/// 过路费,如 @"30元";若 nil 则隐藏
@property (nonatomic, copy, nullable) NSString *tollFee;
/// 营业时间,如 @"00:00-24:00";有值显示,无值显示 -
@property (nonatomic, copy, nullable) NSString *businessHours;
/// 站点联系人,如 @"陈凯";有值显示,无值显示 -
@property (nonatomic, copy, nullable) NSString *contactName;
/// 联系方式,如 @"18019187371";有值显示,无值显示 -
@property (nonatomic, copy, nullable) NSString *contactPhone;
/// 加氢价格,如 @"32元/L";有值显示,无值显示 -
@property (nonatomic, copy, nullable) NSString *hydrogenPrice;
@property (nonatomic, weak, nullable) id<AStationDetailPopupViewDelegate> delegate;
/// 显示弹框动画
- (void)showInView:(UIView *)parentView;
/// 隐藏弹框动画
- (void)hideWithCompletion:(nullable void(^)(void))completion;
/// 隐藏弹框动画(无 completion
- (void)hide;
/// 重置 UI 状态
- (void)resetUI;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,707 @@
//
// AStationDetailPopupView.m
// AMapNavIOSSDK
//
// Created by admin on 2026/3/22.
//
#import "AStationDetailPopupView.h"
#import "AMapNavCommonUtil.h"
#import <Masonry/Masonry.h>
// 绿
static inline UIColor *AStationThemeGreen(void) {
return [UIColor colorWithRed:0x1A/255.0 green:0x7C/255.0 blue:0x43/255.0 alpha:1.0];
}
@interface AStationDetailPopupView ()
///
@property (nonatomic, strong) UIControl *maskControl;
///
@property (nonatomic, strong) UIView *cardView;
///
@property (nonatomic, strong) UILabel *stationNameLabel;
///
@property (nonatomic, strong) UIImageView *costIconView;
@property (nonatomic, strong) UILabel *costLabel;
///
@property (nonatomic, strong) UILabel *addressLabel;
/// 线
@property (nonatomic, strong) UIView *separator;
///
@property (nonatomic, strong) UIImageView *timeIconView;
@property (nonatomic, strong) UILabel *timeLabel;
///
@property (nonatomic, strong) UIImageView *distanceIconView;
@property (nonatomic, strong) UILabel *distanceLabel;
///
@property (nonatomic, strong) UIImageView *tollIconView;
@property (nonatomic, strong) UILabel *tollLabel;
///
@property (nonatomic, strong) UIButton *closeButton;
///
@property (nonatomic, strong) UIButton *startNaviButton;
//
@property (nonatomic, strong) UILabel *businessHoursLabel;
//
@property (nonatomic, strong) UIImageView *contactPersonIconView;
@property (nonatomic, strong) UILabel *contactPersonLabel;
//
@property (nonatomic, strong) UIImageView *priceIconView;
@property (nonatomic, strong) UILabel *priceLabel;
//
@property (nonatomic, strong) UIImageView *phoneIconView;
@property (nonatomic, strong) UILabel *phoneLabel;
@end
@implementation AStationDetailPopupView
#pragma mark - Init
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = [UIColor clearColor];
[self setupUI];
}
return self;
}
#pragma mark - Setup UI
- (void)setupUI {
[self addSubview:self.maskControl];
[self.cardView addSubview:self.closeButton];
[self.cardView addSubview:self.stationNameLabel];
[self.cardView addSubview:self.costLabel];
[self.cardView addSubview:self.businessHoursLabel];
[self.cardView addSubview:self.addressLabel];
[self.cardView addSubview:self.costIconView];
[self.cardView addSubview:self.separator];
[self.cardView addSubview:self.timeIconView];
[self.cardView addSubview:self.timeLabel];
[self.cardView addSubview:self.distanceIconView];
[self.cardView addSubview:self.distanceLabel];
[self.cardView addSubview:self.tollIconView];
[self.cardView addSubview:self.tollLabel];
[self.cardView addSubview:self.contactPersonIconView];
[self.cardView addSubview:self.contactPersonLabel];
[self.cardView addSubview:self.priceIconView];
[self.cardView addSubview:self.priceLabel];
[self.cardView addSubview:self.phoneIconView];
[self.cardView addSubview:self.phoneLabel];
[self.cardView addSubview:self.startNaviButton];
[self setupConstraints];
[self updateUI];
}
#pragma mark - Masonry Constraints
- (void)setupConstraints {
UIView *card = self.cardView;
CGFloat iconSize = 16;
//
[self.maskControl mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self);
}];
// 16
[card mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self).offset(0);
make.right.equalTo(self).offset(-0);
make.bottom.equalTo(self).offset(-0);
}];
//
[self.closeButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(card).offset(8);
make.right.equalTo(card).offset(-15);
make.width.height.mas_equalTo(40);
}];
//
[self.stationNameLabel setContentHuggingPriority:UILayoutPriorityDefaultLow
forAxis:UILayoutConstraintAxisHorizontal];
[self.stationNameLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(card).offset(25);
make.left.equalTo(card).offset(16);
make.right.equalTo(self.closeButton.mas_left).offset(-12);
}];
// 10pt
[self.businessHoursLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.stationNameLabel.mas_bottom).offset(10);
make.left.equalTo(card).offset(16);
make.right.equalTo(card).offset(-16);
}];
// 10pt
[self.addressLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.businessHoursLabel.mas_bottom).offset(10);
make.left.equalTo(card).offset(16);
make.right.equalTo(card).offset(-16);
}];
self.separator.hidden = YES;
// 线10pt
[self.separator mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.addressLabel.mas_bottom).offset(10);
make.left.equalTo(card).offset(16);
make.right.equalTo(card).offset(-16);
make.height.mas_equalTo(0.5);
}];
CGFloat _offset_y = 18;
// 线12pt
[self.timeIconView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.separator.mas_bottom).offset(12);
make.left.equalTo(card).offset(16);
make.width.height.mas_equalTo(iconSize);
}];
[self.timeLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(self.timeIconView);
make.left.equalTo(self.timeIconView.mas_right).offset(6);
make.height.mas_equalTo(24);
}];
/// cost
[self.costIconView mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(self.timeIconView);
make.left.equalTo(self.timeLabel.mas_right).offset(40);
make.width.height.mas_equalTo(iconSize);
}];
[self.costLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(self.costIconView);
make.left.equalTo(self.costIconView.mas_right).offset(6);
make.right.lessThanOrEqualTo(card).offset(-10);
}];
// + 12pt
[self.distanceIconView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.timeIconView.mas_bottom).offset(_offset_y);
make.left.equalTo(card).offset(16);
make.width.height.mas_equalTo(iconSize);
}];
[self.distanceLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(self.distanceIconView);
make.left.equalTo(self.distanceIconView.mas_right).offset(6);
make.width.mas_lessThanOrEqualTo(130);
make.height.mas_equalTo(24);
}];
[self.tollIconView mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(self.distanceIconView);
make.left.equalTo(self.costIconView.mas_left);
make.width.height.mas_equalTo(iconSize);
}];
[self.tollLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(self.distanceIconView);
make.left.equalTo(self.tollIconView.mas_right).offset(6);
make.height.mas_equalTo(24);
}];
// 14pt
[self.contactPersonIconView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.distanceIconView.mas_bottom).offset(_offset_y);
make.left.equalTo(card).offset(16);
make.width.height.mas_equalTo(iconSize);
}];
[self.contactPersonLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(self.contactPersonIconView);
make.left.equalTo(self.contactPersonIconView.mas_right).offset(6);
// make.height.mas_equalTo(24);
make.width.lessThanOrEqualTo(self).multipliedBy(0.4);
}];
// costIconView
[self.priceIconView mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(self.contactPersonIconView);
make.left.equalTo(self.costIconView.mas_left);
make.width.height.mas_equalTo(iconSize);
}];
[self.priceLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(self.contactPersonIconView);
make.left.equalTo(self.priceIconView.mas_right).offset(6);
make.right.lessThanOrEqualTo(card).offset(-10);
make.height.mas_equalTo(24);
}];
// 12pt
[self.phoneIconView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.contactPersonIconView.mas_bottom).offset(_offset_y);
make.left.equalTo(card).offset(16);
make.width.height.mas_equalTo(iconSize);
}];
[self.phoneLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(self.phoneIconView);
make.left.equalTo(self.phoneIconView.mas_right).offset(6);
make.height.mas_equalTo(24);
}];
// 18pt safeArea
[self.startNaviButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.phoneIconView.mas_bottom).offset(40);
make.left.equalTo(card).offset(16);
make.right.equalTo(card).offset(-16);
make.height.mas_equalTo(48);
make.bottom.equalTo(card).offset(-AMP_TabbarSafeBottomMargin + (-AMP_TabbarHeight - 13));
}];
}
#pragma mark - Public
- (void)showInView:(UIView *)parentView {
self.alpha = 0;
self.maskControl.alpha = 0;
[parentView addSubview:self];
[self mas_remakeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(parentView);
}];
[self playShowAnimation];
}
- (void)hide {
[self hideWithCompletion:nil];
}
- (void)hideWithCompletion:(void(^)(void))completion {
[self playDismissAnimationWithCompletion:^{
[self removeFromSuperview];
if (completion) {
completion();
}
}];
}
#pragma mark - Setter Override
- (void)setPointModel:(ANavPointModel *)pointModel {
_pointModel = pointModel;
[self updateUI];
}
- (void)setEstimatedCost:(NSString *)estimatedCost {
_estimatedCost = [estimatedCost copy];
[self updateUI];
}
- (void)setEstimatedTime:(NSString *)estimatedTime {
_estimatedTime = [estimatedTime copy];
[self updateUI];
}
- (void)setDriveDistance:(NSString *)driveDistance {
_driveDistance = [driveDistance copy];
[self updateUI];
}
- (void)setTollFee:(NSString *)tollFee {
_tollFee = [tollFee copy];
[self updateUI];
}
- (void)setBusinessHours:(NSString *)businessHours {
_businessHours = [businessHours copy];
[self updateUI];
}
- (void)setContactName:(NSString *)contactName {
_contactName = [contactName copy];
[self updateUI];
}
- (void)setContactPhone:(NSString *)contactPhone {
_contactPhone = [contactPhone copy];
[self updateUI];
}
- (void)setHydrogenPrice:(NSString *)hydrogenPrice {
_hydrogenPrice = [hydrogenPrice copy];
[self updateUI];
}
#pragma mark - Data Update
- (void)updateUI {
self.stationNameLabel.text = (self.pointModel.name.length > 0)
? self.pointModel.name : @"-";
//
self.businessHoursLabel.text = (self.businessHours.length > 0)
? [NSString stringWithFormat:@"营业时间:%@", self.businessHours]
: @"营业时间:-";
self.costLabel.text = ((self.estimatedCost.length > 0) && [self.estimatedCost doubleValue])
? [NSString stringWithFormat:@"预计加氢费用:%@元", self.estimatedCost]
: @"预计加氢费用:-";
self.addressLabel.text = (self.pointModel.address.length > 0)
? self.pointModel.address : @"-";
// "-- 分钟"
self.timeLabel.text = ((self.estimatedTime.length > 0) && [self.estimatedTime doubleValue] > 0)
? [NSString stringWithFormat:@"预计时间:%@分钟", self.estimatedTime]
: @"预计时间:-";
// "-- 公里"
self.distanceLabel.text = ((self.driveDistance.length > 0) && [self.driveDistance doubleValue] > 0)
? [NSString stringWithFormat:@"行驶里程:%@公里", self.driveDistance]
: @"行驶里程:-";
// "-- 元"
self.tollLabel.text = (self.tollFee.length > 0)
? [NSString stringWithFormat:@"过路费:%@元", self.tollFee]
: @"过路费:-";
// -
self.contactPersonLabel.text = (self.contactName.length > 0)
? [NSString stringWithFormat:@"站联系人:%@", self.contactName]
: @"站联系人:-";
// -
self.priceLabel.text = (self.hydrogenPrice.length > 0)
? [NSString stringWithFormat:@"加氢价格:%@/L", self.hydrogenPrice]
: @"加氢价格:-";
// -
self.phoneLabel.text = (self.contactPhone.length > 0)
? [NSString stringWithFormat:@"联系方式:%@", self.contactPhone]
: @"联系方式:-";
}
- (void)resetUI {
self.stationNameLabel.text = @"-";
self.businessHoursLabel.text = @"营业时间:-";
self.costLabel.text = @"预计加氢费用:-";
self.addressLabel.text = @"地址:-";
self.timeLabel.text = @"预计时间:-";
self.distanceLabel.text = @"行驶里程:-";
self.tollLabel.text = @"过路费:-";
self.contactPersonLabel.text = @"站联系人:-";
self.priceLabel.text = @"加氢价格:-";
self.phoneLabel.text = @"联系方式:-";
}
#pragma mark - Animation
/**
*/
- (void)playShowAnimation {
//
[self.cardView mas_remakeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self).offset(0);
make.right.equalTo(self).offset(-0);
make.top.equalTo(self.mas_bottom).offset(0);
}];
[self layoutIfNeeded];
//
[self.cardView mas_remakeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self).offset(0);
make.right.equalTo(self).offset(-0);
make.bottom.equalTo(self).offset(0);
}];
[UIView animateWithDuration:0.36
delay:0
usingSpringWithDamping:0.82
initialSpringVelocity:0.5
options:UIViewAnimationOptionCurveEaseOut
animations:^{
self.alpha = 1;
self.maskControl.alpha = 1;
[self layoutIfNeeded];
} completion:nil];
}
- (void)playDismissAnimationWithCompletion:(void(^)(void))completion {
[self.cardView mas_remakeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self).offset(0);
make.right.equalTo(self).offset(-0);
make.top.equalTo(self.mas_bottom).offset(20);
}];
[UIView animateWithDuration:0.25
delay:0
options:UIViewAnimationOptionCurveEaseIn
animations:^{
self.maskControl.alpha = 0;
[self layoutIfNeeded];
} completion:^(BOOL finished) {
if (completion) completion();
}];
}
#pragma mark - Actions
- (void)onMaskTapped {
if ([self.delegate respondsToSelector:@selector(stationDetailPopupViewDidTapClose:)]) {
[self.delegate stationDetailPopupViewDidTapClose:self];
}
[self hide];
}
- (void)onCloseTapped {
if ([self.delegate respondsToSelector:@selector(stationDetailPopupViewDidTapClose:)]) {
[self.delegate stationDetailPopupViewDidTapClose:self];
}
[self hide];
}
- (void)onStartNaviTapped {
__weak typeof(self) weakSelf = self;
[self hideWithCompletion:^{
__strong typeof(weakSelf) strongSelf = weakSelf;
if ([strongSelf.delegate respondsToSelector:@selector(stationDetailPopupViewDidTapStartNavi:)]) {
[strongSelf.delegate stationDetailPopupViewDidTapStartNavi:strongSelf];
}
}];
}
#pragma mark - Lazy Load
- (UIControl *)maskControl {
if (!_maskControl) {
_maskControl = [[UIControl alloc] init];
_maskControl.backgroundColor = [UIColor colorWithWhite:0 alpha:0];
[_maskControl addTarget:self action:@selector(onMaskTapped) forControlEvents:UIControlEventTouchUpInside];
}
return _maskControl;
}
- (UIView *)cardView {
if (!_cardView) {
_cardView = [[UIView alloc] init];
_cardView.backgroundColor = [UIColor whiteColor];
_cardView.layer.cornerRadius = 16;
_cardView.layer.masksToBounds = NO;
_cardView.layer.shadowColor = [UIColor blackColor].CGColor;
_cardView.layer.shadowOpacity = 0.15;
_cardView.layer.shadowRadius = 12;
_cardView.layer.shadowOffset = CGSizeMake(0, -4);
[self addSubview:_cardView];
}
return _cardView;
}
- (UIButton *)closeButton {
if (!_closeButton) {
_closeButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_closeButton setImage:[AMapNavCommonUtil imageWithName:@"icon_close"] forState:UIControlStateNormal];
[_closeButton setTitleColor:[UIColor colorWithWhite:0.5 alpha:1] forState:UIControlStateNormal];
_closeButton.titleLabel.font = [UIFont systemFontOfSize:16];
[_closeButton addTarget:self action:@selector(onCloseTapped) forControlEvents:UIControlEventTouchUpInside];
}
return _closeButton;
}
- (UILabel *)stationNameLabel {
if (!_stationNameLabel) {
_stationNameLabel = [[UILabel alloc] init];
_stationNameLabel.font = [UIFont hp_pingFangMedium:18];
_stationNameLabel.textColor = [UIColor hp_colorWithRGBHex:0x1D2129];
_stationNameLabel.numberOfLines = 2;
_stationNameLabel.minimumScaleFactor = 0.8;
}
return _stationNameLabel;
}
- (UILabel *)costLabel {
if (!_costLabel) {
_costLabel = [[UILabel alloc] init];
_costLabel.font = [UIFont hp_pingFangMedium:14];
_costLabel.textColor = [UIColor hp_colorWithRGBHex:0x1D2129];
_costLabel.numberOfLines = 1;
_costLabel.textAlignment = NSTextAlignmentLeft;
}
return _costLabel;
}
- (UILabel *)businessHoursLabel {
if (!_businessHoursLabel) {
_businessHoursLabel = [[UILabel alloc] init];
_businessHoursLabel.font = [UIFont hp_pingFangRegular:14];
_businessHoursLabel.textColor = [UIColor hp_colorWithRGBHex:0x1D2129];
_businessHoursLabel.numberOfLines = 1;
}
return _businessHoursLabel;
}
- (UILabel *)addressLabel {
if (!_addressLabel) {
_addressLabel = [[UILabel alloc] init];
_addressLabel.font = [UIFont hp_pingFangRegular:14];
_addressLabel.textColor = [UIColor hp_colorWithRGBHex:0x86909C];
_addressLabel.numberOfLines = 2;
}
return _addressLabel;
}
- (UIImageView *)costIconView {
if (!_costIconView) {
_costIconView = [[UIImageView alloc] init];
_costIconView.contentMode = UIViewContentModeScaleAspectFit;
_costIconView.image = [AMapNavCommonUtil imageWithName3x:@"ic_fuel"];
}
return _costIconView;
}
- (UIView *)separator {
if (!_separator) {
_separator = [[UIView alloc] init];
_separator.backgroundColor = [UIColor colorWithWhite:0.88 alpha:1];
_separator.hidden = YES;
}
return _separator;
}
- (UIImageView *)timeIconView {
if (!_timeIconView) {
_timeIconView = [[UIImageView alloc] init];
_timeIconView.contentMode = UIViewContentModeScaleAspectFit;
_timeIconView.image = [AMapNavCommonUtil imageWithName3x:@"ic_time"];
}
return _timeIconView;
}
- (UILabel *)timeLabel {
if (!_timeLabel) {
_timeLabel = [[UILabel alloc] init];
_timeLabel.font = [UIFont hp_pingFangMedium:14];
_timeLabel.textColor = [UIColor hp_colorWithRGBHex:0x1D2129];
}
return _timeLabel;
}
- (UIImageView *)distanceIconView {
if (!_distanceIconView) {
_distanceIconView = [[UIImageView alloc] init];
_distanceIconView.contentMode = UIViewContentModeScaleAspectFit;
_distanceIconView.image = [AMapNavCommonUtil imageWithName3x:@"ic_mileage"];
}
return _distanceIconView;
}
- (UILabel *)distanceLabel {
if (!_distanceLabel) {
_distanceLabel = [[UILabel alloc] init];
_distanceLabel.font = [UIFont hp_pingFangMedium:14];
_distanceLabel.textColor = [UIColor hp_colorWithRGBHex:0x1D2129];
}
return _distanceLabel;
}
- (UIImageView *)tollIconView {
if (!_tollIconView) {
_tollIconView = [[UIImageView alloc] init];
_tollIconView.contentMode = UIViewContentModeScaleAspectFit;
_tollIconView.image = [AMapNavCommonUtil imageWithName3x:@"ic_toll"];
}
return _tollIconView;
}
- (UILabel *)tollLabel {
if (!_tollLabel) {
_tollLabel = [[UILabel alloc] init];
_tollLabel.font = [UIFont hp_pingFangMedium:14];
_tollLabel.textColor = [UIColor hp_colorWithRGBHex:0x1D2129];
}
return _tollLabel;
}
- (UIImageView *)contactPersonIconView {
if (!_contactPersonIconView) {
_contactPersonIconView = [[UIImageView alloc] init];
_contactPersonIconView.contentMode = UIViewContentModeScaleAspectFit;
_contactPersonIconView.image = [AMapNavCommonUtil imageWithName3x:@"ic_person"];
}
return _contactPersonIconView;
}
- (UILabel *)contactPersonLabel {
if (!_contactPersonLabel) {
_contactPersonLabel = [[UILabel alloc] init];
_contactPersonLabel.font = [UIFont hp_pingFangMedium:14];
_contactPersonLabel.textColor = [UIColor hp_colorWithRGBHex:0x1D2129];
}
return _contactPersonLabel;
}
- (UIImageView *)priceIconView {
if (!_priceIconView) {
_priceIconView = [[UIImageView alloc] init];
_priceIconView.contentMode = UIViewContentModeScaleAspectFit;
_priceIconView.image = [AMapNavCommonUtil imageWithName3x:@"ic_price"];
}
return _priceIconView;
}
- (UILabel *)priceLabel {
if (!_priceLabel) {
_priceLabel = [[UILabel alloc] init];
_priceLabel.font = [UIFont hp_pingFangMedium:14];
_priceLabel.textColor = [UIColor hp_colorWithRGBHex:0x1D2129];
}
return _priceLabel;
}
- (UIImageView *)phoneIconView {
if (!_phoneIconView) {
_phoneIconView = [[UIImageView alloc] init];
_phoneIconView.contentMode = UIViewContentModeScaleAspectFit;
_phoneIconView.image = [AMapNavCommonUtil imageWithName3x:@"ic_phone"];
}
return _phoneIconView;
}
- (UILabel *)phoneLabel {
if (!_phoneLabel) {
_phoneLabel = [[UILabel alloc] init];
_phoneLabel.font = [UIFont hp_pingFangMedium:14];
_phoneLabel.textColor = [UIColor hp_colorWithRGBHex:0x1D2129];
}
return _phoneLabel;
}
- (UIButton *)startNaviButton {
if (!_startNaviButton) {
_startNaviButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_startNaviButton setTitle:@"开始导航" forState:UIControlStateNormal];
[_startNaviButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
_startNaviButton.titleLabel.font = [UIFont boldSystemFontOfSize:17];
_startNaviButton.backgroundColor = AStationThemeGreen();
_startNaviButton.layer.cornerRadius = 24;
[_startNaviButton addTarget:self action:@selector(onStartNaviTapped) forControlEvents:UIControlEventTouchUpInside];
}
return _startNaviButton;
}
@end

View File

@@ -37,6 +37,8 @@
</array> </array>
<key>LSRequiresIPhoneOS</key> <key>LSRequiresIPhoneOS</key>
<true/> <true/>
<key>LSSupportsOpeningDocumentsInPlace</key>
<true/>
<key>NSCameraUsageDescription</key> <key>NSCameraUsageDescription</key>
<string>需要访问您的相机以扫描二维码</string> <string>需要访问您的相机以扫描二维码</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key> <key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
@@ -57,6 +59,8 @@
<string>fetch</string> <string>fetch</string>
<string>location</string> <string>location</string>
</array> </array>
<key>UIFileSharingEnabled</key>
<true/>
<key>UILaunchStoryboardName</key> <key>UILaunchStoryboardName</key>
<string>LaunchScreen</string> <string>LaunchScreen</string>
<key>UIMainStoryboardFile</key> <key>UIMainStoryboardFile</key>
@@ -76,26 +80,22 @@
</array> </array>
<key>uses</key> <key>uses</key>
<string></string> <string></string>
<key>NSAppTransportSecurity</key>
<dict>
<key>UIBackgroundModes</key> <key>NSAllowsArbitraryLoads</key>
<array> <true/>
<string>remote-notification</string> <key>NSExceptionDomains</key>
<string>fetch</string> <dict>
</array> <key>47.101.201.13</key>
<dict>
<key>CFBundleLocalizations</key> <key>NSExceptionAllowsInsecureHTTPLoads</key>
<array> <true/>
<string>zh-Hans</string> <key>NSIncludesSubdomains</key>
<string>en</string> <true/>
</array> <key>NSExceptionMinimumTLSVersion</key>
<string>TLSv1.0</string>
<key>UIFileSharingEnabled</key> </dict>
<true/> </dict>
<!-- 允许在“文件”App中直接打开文档 --> </dict>
<key>LSSupportsOpeningDocumentsInPlace</key>
<true/>
</dict> </dict>
</plist> </plist>

View File

@@ -8,11 +8,11 @@ class AppTheme {
static const Color themeColor = Color(0xFF017137); static const Color themeColor = Color(0xFF017137);
//是否开放域名切换 //是否开放域名切换
static const bool is_show_host = true; static const bool is_show_host = false;
//http://192.168.110.222:8080/ //http://192.168.110.222:8080/
//http://192.168.110.44:8080/ //http://192.168.110.44:8080/
static String test_service_url = "https://beta-esg.api.lnh2e.com/"; static String test_service_url = "http://47.101.201.13:8443/api/";
static const String release_service_url = ""; static const String release_service_url = "";
//加氢站相关查询 //加氢站相关查询

View File

@@ -17,7 +17,7 @@ void main() async {
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
WidgetsBinding widgetsBinding = await init( WidgetsBinding widgetsBinding = await init(
isDebug: true, isDebug: false,
logTag: '小羚羚', logTag: '小羚羚',
supportedLocales: [const Locale('zh', 'CN')], supportedLocales: [const Locale('zh', 'CN')],
); );
@@ -35,7 +35,7 @@ void main() async {
// 设计稿尺寸 单位dp // 设计稿尺寸 单位dp
designSize: const Size(390, 844), designSize: const Size(390, 844),
// Getx Log // Getx Log
enableLog: true, enableLog: false,
// 默认的跳转动画 // 默认的跳转动画
defaultTransition: Transition.rightToLeft, defaultTransition: Transition.rightToLeft,
// 主题模式 // 主题模式

View File

@@ -7,6 +7,7 @@ import 'package:ln_jq_app/pages/c_page/car_info/view.dart';
import 'package:ln_jq_app/pages/c_page/mine/view.dart'; import 'package:ln_jq_app/pages/c_page/mine/view.dart';
import 'package:ln_jq_app/pages/c_page/reservation/view.dart'; import 'package:ln_jq_app/pages/c_page/reservation/view.dart';
import '../mall/mall_view.dart';
import 'index.dart'; import 'index.dart';
class BaseWidgetsPage extends GetView<BaseWidgetsController> { class BaseWidgetsPage extends GetView<BaseWidgetsController> {
@@ -33,7 +34,7 @@ class BaseWidgetsPage extends GetView<BaseWidgetsController> {
} }
List<Widget> _buildPages() { List<Widget> _buildPages() {
return [ReservationPage(), NativePageIOS(), CarInfoPage(), MinePage()]; return [ReservationPage(), NativePageIOS(), MallPage(), CarInfoPage(), MinePage()];
} }
// 自定义导航栏 (悬浮胶囊样式) // 自定义导航栏 (悬浮胶囊样式)

View File

@@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts # In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix. # of the product and file versions while build-number is used as the build suffix.
version: 1.2.4+7 version: 1.2.5+8
environment: environment:
sdk: ^3.9.0 sdk: ^3.9.0