diff --git a/assets/mapbox_map.html b/assets/mapbox_map.html
index eb47f2e..4ed79fe 100644
--- a/assets/mapbox_map.html
+++ b/assets/mapbox_map.html
@@ -14848,8 +14848,8 @@
el.addEventListener("click", function (e) {
e.stopPropagation();
showTrainDetails(lat, lng, recordData);
- if (window.flutter_inappwebview) {
- window.flutter_inappwebview.callHandler("showTrainDetails", {
+ if (window.showTrainDetails) {
+ window.showTrainDetails.postMessage(JSON.stringify({
id: recordData.id || Date.now(),
trainNumber: trainNumber || "未知车次",
trainType: recordData.trainType || "未知类型",
@@ -14858,7 +14858,7 @@
latitude: lat,
longitude: lng,
timestamp: Date.now(),
- });
+ }));
}
});
const marker = new maplibregl.Marker({
@@ -14931,11 +14931,21 @@
.addTo(map);
}
function setCenter(lat, lng, zoom, bearing) {
- map.jumpTo({
+ if (!window.map) {
+ console.error("[JS] Map object not ready in setCenter");
+ return;
+ }
+
+ window.map.jumpTo({
center: [lng, lat],
- zoom: zoom !== undefined ? zoom : map.getZoom(),
- bearing: bearing !== undefined ? bearing : map.getBearing(),
+ zoom: zoom !== undefined ? zoom : window.map.getZoom(),
+ bearing: bearing !== undefined ? bearing : window.map.getBearing(),
});
+
+ const mapContainer = window.map.getContainer();
+ if (mapContainer.style.opacity === "0") {
+ mapContainer.style.opacity = "1";
+ }
}
function getMapState() {
const center = map.getCenter();
@@ -14948,17 +14958,19 @@
}
function setupMapEventListeners() {
if (!map) return;
- map.on("moveend", function () {
+ map.on("move", function () {
const center = map.getCenter();
const zoom = map.getZoom();
const bearing = map.getBearing();
- if (window.flutter_inappwebview) {
- window.flutter_inappwebview.callHandler("onMapStateChanged", {
+
+ if (window.onMapStateChanged) {
+ const mapState = JSON.stringify({
lat: center.lat,
lng: center.lng,
zoom: zoom,
bearing: bearing,
});
+ window.onMapStateChanged.postMessage(mapState);
}
});
}
diff --git a/lib/screens/map_webview_screen.dart b/lib/screens/map_webview_screen.dart
index 45c6778..d86967b 100644
--- a/lib/screens/map_webview_screen.dart
+++ b/lib/screens/map_webview_screen.dart
@@ -32,13 +32,41 @@ class MapWebViewScreenState extends State
double _currentRotation = 0.0;
LatLng? _currentLocation;
LatLng? _lastTrainLocation;
+ bool _isDataLoaded = false;
+ final Completer _webViewReadyCompleter = Completer();
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
_initializeWebView();
- _initializeServices();
+ _startInitialization();
+ }
+
+ Future _startInitialization() async {
+ setState(() {
+ _isLoading = true;
+ });
+
+ try {
+ await _loadSettings();
+ await _loadTrainRecordsFromDatabase();
+
+ await _webViewReadyCompleter.future;
+
+ _initializeMapCamera();
+
+ _initializeLocation();
+ _startAutoRefresh();
+ } catch (e, s) {
+ print('[Flutter] Init Map WebView Screen Failed: $e\n$s');
+ } finally {
+ if (mounted) {
+ setState(() {
+ _isLoading = false;
+ });
+ }
+ }
}
@override
@@ -48,16 +76,7 @@ class MapWebViewScreenState extends State
}
}
- Future _initializeServices() async {
- try {
- await _loadSettings();
- await _loadTrainRecordsFromDatabase();
- _initializeLocation();
- _startAutoRefresh();
- } catch (e) {}
- }
-
- void _initializeWebView() {
+ Future _initializeWebView() async {
_controller = WebViewController()
..setJavaScriptMode(JavaScriptMode.unrestricted)
..setBackgroundColor(const Color(0xFF121212))
@@ -92,9 +111,8 @@ class MapWebViewScreenState extends State
_isLoading = false;
});
- if (mounted) {
- _initializeMap();
- _initializeLocation();
+ if (!_webViewReadyCompleter.isCompleted) {
+ _webViewReadyCompleter.complete();
}
},
onWebResourceError: (WebResourceError error) {
@@ -107,6 +125,8 @@ class MapWebViewScreenState extends State
..loadFlutterAsset('assets/mapbox_map.html')
.then((_) {})
.catchError((error) {});
+
+ await Future.delayed(const Duration(milliseconds: 500));
}
Future _initializeLocation() async {
@@ -266,10 +286,6 @@ class MapWebViewScreenState extends State
} else {}
} else {}
} else {}
-
- if (mounted) {
- _initializeMapPosition();
- }
});
Future.delayed(const Duration(milliseconds: 3000), () {
@@ -351,25 +367,38 @@ class MapWebViewScreenState extends State
}
}
- void _initializeMapPosition() {
+ void _initializeMapCamera() {
if (_isMapInitialized) return;
- LatLng? targetLocation;
+ LatLng targetLocation;
+ double targetZoom = _currentZoom;
+ double targetRotation = _currentRotation;
- if (_lastTrainLocation != null) {
- targetLocation = _lastTrainLocation;
- } else if (_currentPosition != null) {
- targetLocation =
- LatLng(_currentPosition!.latitude, _currentPosition!.longitude);
- }
-
- if (targetLocation != null) {
- _centerMap(targetLocation,
- zoom: _currentZoom, rotation: _currentRotation);
- _isMapInitialized = true;
+ if (_currentLocation != null) {
+ targetLocation = _currentLocation!;
+ } else if (_lastTrainLocation != null) {
+ targetLocation = _lastTrainLocation!;
+ targetZoom = 14.0;
+ targetRotation = 0.0;
} else {
- _isMapInitialized = true;
+ targetLocation = const LatLng(39.9042, 116.4074);
+ targetZoom = 10.0;
}
+
+ _centerMap(targetLocation, zoom: targetZoom, rotation: targetRotation);
+ _isMapInitialized = true;
+
+ Future.delayed(const Duration(milliseconds: 500), () {
+ if (mounted) {
+ _updateUserLocation();
+ _updateTrainMarkers();
+ _controller.runJavaScript('''
+ if (window.MapInterface) {
+ window.MapInterface.setRailwayVisible($_isRailwayLayerVisible);
+ }
+ ''');
+ }
+ });
}
void _centerMap(LatLng location, {double? zoom, double? rotation}) {
@@ -430,91 +459,6 @@ class MapWebViewScreenState extends State
} catch (e) {}
}
- Future _initializeMap() async {
- try {
- LatLng? targetLocation;
- double targetZoom = 14.0;
- double targetRotation = _currentRotation;
-
- if (_lastTrainLocation != null) {
- targetLocation = _lastTrainLocation;
- targetZoom = 14.0;
- targetRotation = 0.0;
- } else if (_currentPosition != null) {
- targetLocation =
- LatLng(_currentPosition!.latitude, _currentPosition!.longitude);
- targetZoom = 16.0;
- targetRotation = 0.0;
- }
-
- if (targetLocation != null) {
- _centerMap(targetLocation, zoom: targetZoom, rotation: targetRotation);
-
- try {
- await _controller.runJavaScript('''
- (function() {
- if (window.map && window.map.getContainer) {
- window.map.getContainer().style.opacity = '1';
- return true;
- } else {
- return false;
- }
- })();
- ''');
- } catch (e) {
- print('显示地图失败: $e');
- Future.delayed(const Duration(milliseconds: 500), () {
- _controller.runJavaScript('''
- (function() {
- if (window.map && window.map.getContainer) {
- window.map.getContainer().style.opacity = '1';
- console.log('延迟显示地图成功');
- }
- })();
- ''');
- });
- }
- }
-
- setState(() {
- _isMapInitialized = true;
- });
- } catch (e, stackTrace) {}
-
- Future.delayed(const Duration(milliseconds: 1000), () {
- if (mounted && _isMapInitialized) {
- _updateTrainMarkers();
-
- _controller.runJavaScript('''
- (function() {
- if (window.MapInterface) {
- try {
- window.MapInterface.setRailwayVisible($_isRailwayLayerVisible);
- console.log('初始化铁路图层状态: $_isRailwayLayerVisible');
- } catch (error) {
- console.error('初始化铁路图层失败:', error);
- }
- }
- })();
- ''');
- }
- });
-
- Future.delayed(const Duration(milliseconds: 3000), () {
- if (mounted && _isMapInitialized) {
- _updateTrainMarkers();
- }
- });
-
- Future.delayed(const Duration(seconds: 5), () {
- if (mounted && _isLoading) {
- setState(() {
- _isLoading = false;
- });
- }
- });
- }
-
LatLng? _parseDmsCoordinate(String? positionInfo) {
if (positionInfo == null ||
positionInfo.isEmpty ||
@@ -943,10 +887,10 @@ class MapWebViewScreenState extends State
void _onMapStateChanged(Map mapState) {
try {
- final lat = mapState['lat'] as double;
- final lng = mapState['lng'] as double;
- final zoom = mapState['zoom'] as double;
- final bearing = mapState['bearing'] as double;
+ final lat = (mapState['lat'] as num).toDouble();
+ final lng = (mapState['lng'] as num).toDouble();
+ final zoom = (mapState['zoom'] as num).toDouble();
+ final bearing = (mapState['bearing'] as num).toDouble();
setState(() {
_currentLocation = LatLng(lat, lng);
diff --git a/lib/services/database_service.dart b/lib/services/database_service.dart
index 482212e..3d0dd92 100644
--- a/lib/services/database_service.dart
+++ b/lib/services/database_service.dart
@@ -13,7 +13,7 @@ class DatabaseService {
DatabaseService._internal();
static const String _databaseName = 'train_database';
- static const _databaseVersion = 6;
+ static const _databaseVersion = 7;
static const String trainRecordsTable = 'train_records';
static const String appSettingsTable = 'app_settings';
@@ -87,6 +87,10 @@ class DatabaseService {
await db.execute(
'ALTER TABLE $appSettingsTable ADD COLUMN hideUngroupableRecords INTEGER NOT NULL DEFAULT 0');
}
+ if (oldVersion < 7) {
+ await db.execute(
+ 'ALTER TABLE $appSettingsTable ADD COLUMN mapSettingsTimestamp INTEGER');
+ }
}
Future _onCreate(Database db, int version) async {
@@ -136,7 +140,8 @@ class DatabaseService {
groupBy TEXT NOT NULL DEFAULT 'trainAndLoco',
timeWindow TEXT NOT NULL DEFAULT 'unlimited',
mapTimeFilter TEXT NOT NULL DEFAULT 'unlimited',
- hideUngroupableRecords INTEGER NOT NULL DEFAULT 0
+ hideUngroupableRecords INTEGER NOT NULL DEFAULT 0,
+ mapSettingsTimestamp INTEGER
)
''');
@@ -164,6 +169,7 @@ class DatabaseService {
'timeWindow': 'unlimited',
'mapTimeFilter': 'unlimited',
'hideUngroupableRecords': 0,
+ 'mapSettingsTimestamp': null,
});
}
diff --git a/pubspec.yaml b/pubspec.yaml
index 3134fd5..e591ac7 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -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
# 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.
-version: 0.5.0-flutter+50
+version: 0.5.1-flutter+51
environment:
sdk: ^3.5.4