From 3aac4e7330a3257ffecf9f133f004324e35cb075 Mon Sep 17 00:00:00 2001 From: userGyl Date: Thu, 26 Mar 2026 18:01:05 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E6=95=B4=E5=9C=B0=E5=9B=BE=E9=80=89?= =?UTF-8?q?=E7=82=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/lnkj/ln_jq_app/NativeMapView.java | 114 ++++++++++++++---- .../app/src/main/res/drawable/ic_marker.png | Bin 0 -> 2681 bytes .../src/main/res/drawable/ic_un_marker.png | Bin 0 -> 1859 bytes 3 files changed, 88 insertions(+), 26 deletions(-) create mode 100644 ln_jq_app/android/app/src/main/res/drawable/ic_marker.png create mode 100644 ln_jq_app/android/app/src/main/res/drawable/ic_un_marker.png diff --git a/ln_jq_app/android/app/src/main/java/com/lnkj/ln_jq_app/NativeMapView.java b/ln_jq_app/android/app/src/main/java/com/lnkj/ln_jq_app/NativeMapView.java index d3dfc36..68d6b44 100644 --- a/ln_jq_app/android/app/src/main/java/com/lnkj/ln_jq_app/NativeMapView.java +++ b/ln_jq_app/android/app/src/main/java/com/lnkj/ln_jq_app/NativeMapView.java @@ -4,7 +4,9 @@ import android.app.Activity; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; +import android.graphics.Canvas; import android.graphics.Color; +import android.graphics.PorterDuff; import android.graphics.Typeface; import android.graphics.drawable.GradientDrawable; import android.os.Build; @@ -39,6 +41,7 @@ import com.amap.api.maps.CameraUpdateFactory; import com.amap.api.maps.LocationSource; import com.amap.api.maps.MapView; import com.amap.api.maps.MapsInitializer; +import com.amap.api.maps.model.BitmapDescriptor; import com.amap.api.maps.model.BitmapDescriptorFactory; import com.amap.api.maps.model.LatLng; import com.amap.api.maps.model.Marker; @@ -92,8 +95,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, Inputtips.InputtipsListener { private static final String TAG = "NativeMapView"; private final FrameLayout container; @@ -316,8 +318,7 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation tvStationName.setTextSize(18); tvStationName.setTextColor(Color.BLACK); tvStationName.setTypeface(Typeface.DEFAULT_BOLD); - LinearLayout.LayoutParams nameParams = new LinearLayout.LayoutParams( - 0, ViewGroup.LayoutParams.WRAP_CONTENT, 1.0f); + LinearLayout.LayoutParams nameParams = new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 1.0f); titleLayout.addView(tvStationName, nameParams); // 关闭按钮 (X) @@ -398,9 +399,7 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation // 开始规划前隐藏输入框面板 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.calculateDriveRouteAsyn(query); } @@ -466,10 +465,7 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation //防止 parseDouble 崩溃 if (latStr != null && !latStr.isEmpty() && lngStr != null && !lngStr.isEmpty()) { try { - finalDestinationLatLng = new LatLng( - Double.parseDouble(latStr), - Double.parseDouble(lngStr) - ); + finalDestinationLatLng = new LatLng(Double.parseDouble(latStr), Double.parseDouble(lngStr)); if (truckRouteData.destinationSite.name != null && !truckRouteData.destinationSite.name.isEmpty()) { finalDestinationName = truckRouteData.destinationSite.name; } @@ -582,9 +578,7 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation json.put("plateNumber", plateNumber); json.put("hydrogenSiteId", selectedSiteId); - Request.Builder requestBuilder = new Request.Builder() - .url(mDebugUrl + "truck/truckRouteAlgorithm") - .post(RequestBody.create(json.toString(), MediaType.parse("application/json"))); + Request.Builder requestBuilder = new Request.Builder().url(mDebugUrl + "truck/truckRouteAlgorithm").post(RequestBody.create(json.toString(), MediaType.parse("application/json"))); if (token != null && !token.isEmpty()) { requestBuilder.addHeader("asoco-token", token); @@ -780,8 +774,11 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation try { JSONObject item = array.getJSONObject(i); String id = item.getString("id"); - markStation(new LatLng(item.getDouble("latitude"), item.getDouble("longitude")), - item.getString("name"), item.getString("address"), id, false); + //推荐站点跳出 + if (selectedSiteId.equals(id)) { + continue; + } + markStation(new LatLng(item.getDouble("latitude"), item.getDouble("longitude")), item.getString("name"), item.getString("address"), id, false); } catch (Exception ignored) { } } @@ -798,13 +795,17 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation } - private void markStation(LatLng latLng, String name, String address, String stationId, - boolean isRecommend) { - MarkerOptions markerOptions = new MarkerOptions() - .position(latLng).title(name) - .icon(BitmapDescriptorFactory.defaultMarker( - isRecommend ? BitmapDescriptorFactory.HUE_RED - : BitmapDescriptorFactory.HUE_GREEN)); + private void markStation(LatLng latLng, String name, String address, String stationId, boolean isRecommend) { + + String displayName = name; + if (displayName != null && displayName.length() > 7) { + displayName = displayName.substring(0, 7) + "..."; + } + + BitmapDescriptor icon = getMarkerIconWithText(mContext, displayName, isRecommend); + + MarkerOptions markerOptions = new MarkerOptions().position(latLng).icon(icon).anchor(0.5f, 0.8f); // 重点:调整锚点,确保图标尖端对准经纬度 + Marker m = aMap.addMarker(markerOptions); Map dataMap = new HashMap<>(); @@ -818,8 +819,14 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation @Override public boolean onMarkerClick(Marker marker) { - Object obj = marker.getObject(); + //地图选点 + for (Marker m : stationMarkers) { + m.setIcon(BitmapDescriptorFactory.fromResource(m.equals(marker) ? R.drawable.ic_marker : R.drawable.ic_un_marker)); + } + + + Object obj = marker.getObject(); if (obj instanceof Map) { Map dataMap = (Map) obj; @@ -909,6 +916,61 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation mapView.onDestroy(); } + public BitmapDescriptor getMarkerIconWithText(Context context, String text, boolean isRecommend) { + // 创建主容器 + LinearLayout container = new LinearLayout(context); + container.setOrientation(LinearLayout.VERTICAL); + container.setGravity(Gravity.CENTER_HORIZONTAL); + // 必须要给容器本身也设置一个基础参数,否则测量可能失败 + container.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT)); + + // 文字部分:必须显式设置 LayoutParams + TextView textView = new TextView(context); + textView.setText(text); + textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 12); + textView.setTextColor(Color.BLACK); + // 设置文字的参数为 WRAP_CONTENT + LinearLayout.LayoutParams textLp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); + textView.setLayoutParams(textLp); + container.addView(textView); + + // 图标部分:设置固定大小 + ImageView imageView = new ImageView(context); + imageView.setImageResource(isRecommend ? R.drawable.ic_marker : R.drawable.ic_un_marker); + + int size = dp2px(30); + LinearLayout.LayoutParams imgLp = new LinearLayout.LayoutParams(size, size); + imgLp.topMargin = dp2px(2); + imageView.setLayoutParams(imgLp); + imageView.setScaleType(ImageView.ScaleType.FIT_CENTER); + container.addView(imageView); + + // --- 精准测量 --- + int spec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); + container.measure(spec, spec); + + // 获取测量后的实际宽高 + int measuredWidth = container.getMeasuredWidth(); + int measuredHeight = container.getMeasuredHeight(); + + // 如果测出来是 0,说明有问题 + if (measuredWidth <= 0 || measuredHeight <= 0) { + // 兜底逻辑:如果测量失败,给一个默认大小 + measuredWidth = dp2px(100); + measuredHeight = dp2px(60); + } + + container.layout(0, 0, measuredWidth, measuredHeight); + + // 绘制到 Bitmap + Bitmap bitmap = Bitmap.createBitmap(measuredWidth, measuredHeight, Bitmap.Config.ARGB_8888); + Canvas canvas = new Canvas(bitmap); + // 绘制前可以选清空背景(透明) + canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR); + container.draw(canvas); + + return BitmapDescriptorFactory.fromBitmap(bitmap); + } /** * 辅助方法:创建带图标的文本项 @@ -970,7 +1032,7 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation } // 1. 成本计算模式 (高亮绿色头部) - TextView item1 = createMenuItem(context, "成本计算模式", true); + TextView item1 = createMenuItem(context, "成本计算模式", false); item1.setOnClickListener(v -> switchMode("成本计算")); // 2. 送货规划模式 @@ -978,7 +1040,7 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation item2.setOnClickListener(v -> switchMode("送货规划")); // 3. 加氢规划模式 - TextView item3 = createMenuItem(context, "加氢规划模式", false); + TextView item3 = createMenuItem(context, "加氢规划模式", true); item3.setOnClickListener(v -> switchMode("加氢规划")); menu.addView(item1); diff --git a/ln_jq_app/android/app/src/main/res/drawable/ic_marker.png b/ln_jq_app/android/app/src/main/res/drawable/ic_marker.png new file mode 100644 index 0000000000000000000000000000000000000000..abafc0a3947df281016f31df872d17764e13e687 GIT binary patch literal 2681 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 literal 0 HcmV?d00001 diff --git a/ln_jq_app/android/app/src/main/res/drawable/ic_un_marker.png b/ln_jq_app/android/app/src/main/res/drawable/ic_un_marker.png new file mode 100644 index 0000000000000000000000000000000000000000..38dc60d03b4a87a570d68c7ddf5c28a464d8ba2c GIT binary patch literal 1859 zcmV-J2fX-+P)s5QBmvm`j+<`s*+o=Vmf5G_t|Ifwb$AA)U~u67V-1=@#CTC>FLW) zpFW*^^5jV-n_)Z9RxDyx{)F}pFQP^0OOS-rgjo?!35UOZ`&P;H({8u*XO^|w?T}?z zkS#@!BOK8BiVo3GeP6;B6!hT1gP}){9yQc#RK!sPjT6+gr2R}5QMUNX@5~v{`pUzH z4;%OH-5b!Mdj9qlBr&H-rP4nlhb)LN$Y%n{k85l$swCh0L zAf2Knf{P-zfM^x-1Y~I%AC+S|K_seRObsAoDz-Tp696fu zJRTWq8uQq?YSp6won*ufHL)<+v`?MZ2(-9d zfb-=$U)F+^Crx3Lo;VRn(A3lvcZJ8~1}aEn&i&3N>YZ6|-XP_&7A#8EIjXma?E5Ft zG5PS3H%jk$f^>l|#v~DtNFhikR0E5Z<+S9m_C7U&*I2V3IO zkQ5H7=m1HwByl1WY7L2FBEXOFP%f9l=FOYK)~#E^wr$(Oh7B9S^5x5E?tImzT>PA$ z$&dpVJ~=~ZK$IVu635hxq)3EMfrV+GxQp>utXL8D?Aa6c?b{c2?AQ^uZ{Ke0+O;d} z-MiN@awNj_xrHOHBNt*~e9VHbU%$@X8KM!OcrGN?1jN^^TNefg2Ll#@B5c{RB~+_b zPmCJsL5H6XOblrM*NKUV3KQaSp;EETQz1d(lKQV-zuI59a%I@Pdw0;wtw={#jGUc2 zcZM}<)_5wB4;zu`hhBi#>eZ_cmlgY60fhLX%14|*5^Lpn&17iQ)p>yhxja%hBE&^6 zPl$u&Ysb{@7X5wx}RzgK!kuk#DXAP3bwQJY*(YiQ= z$#(E^Xu!1S0W_QpTR~9VpgBR34W=Vl{g*Faio5j@<=rG6_mO2H?t==g@ly;zv#8HE z5P|>_0LjMt_wV~?U7XTtwakG4dI9z8;@6s-f4S5%Bme~w!-h{oEaK(Mm&M)sh`xC7 z!kprYB5di0NLfC0^lWmer^2F4lMBu$a3V3huQOUX%y z;;HcY^XEZ-|Aj`Qp|av%9xplM#@hHw5ifToLHq70TbC9;GB(E*U?Y9>Dby*F5bY_3rGjC4&}%LV1(9^}=%3m;O&JU3W|lNPoL(Z`(34JF%37vmnhZoM7K23#f}BR@&!0aipL@lHHJA`F?d`ACYCpU$ z%ANQ7Q-UJPg$oyWUvc4E5;Lo59V8a_f5t9J5Dhg6UI~K|RK+K@6f9W~%_XD>@Ry4J xMbJ`3bk_d|00960K=#F~00006Nkl