flutter_integrated_whb/lib/customWidget/BaiDuMap/Map_page.dart

206 lines
6.1 KiB
Dart
Raw Normal View History

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:qhd_prevention/customWidget/BaiDuMap/BaiduMapWebView.dart';
import 'package:qhd_prevention/customWidget/toast_util.dart';
import 'package:qhd_prevention/pages/my_appbar.dart';
import 'package:qhd_prevention/services/location_service.dart';
import 'package:qhd_prevention/tools/tools.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:geolocator/geolocator.dart';
class MapPage extends StatefulWidget {
final String gson;
const MapPage({super.key, required this.gson});
@override
State<MapPage> createState() => _MapPageState();
}
class _MapPageState extends State<MapPage> {
late final WebViewController _controller;
bool _isLoading = true;
String? _errorMessage;
double? _longitude;
double? _latitude;
List<dynamic> _gsonList = [];
late Map<String, dynamic> mapData = {};
@override
void initState() {
super.initState();
_initLocation();
}
/// 获取定位(并初始化 WebView 控制器)
Future<void> _initLocation() async {
setState(() {
_isLoading = true;
_errorMessage = null;
});
2025-08-22 09:02:35 +08:00
LoadingDialogHelper.show(message: '地图加载中');
try {
final LocationResult loc = await LocationService.getCurrentLocation(
timeout: const Duration(seconds: 10),
);
// 解析 gson
try {
final parsed = jsonDecode(widget.gson);
if (parsed is List) {
_gsonList = parsed;
} else {
_gsonList = [];
}
} catch (e) {
debugPrint('解析 gson 失败: $e');
_gsonList = [];
}
if (!mounted) return;
setState(() {
_longitude = loc.longitudeAsDouble;
_latitude = loc.latitudeAsDouble;
});
// 初始化 WebViewController 并加载本地页面
_controller = WebViewController()
..setJavaScriptMode(JavaScriptMode.unrestricted)
// 注册 JS 通道 'JS' —— 对应 HTML 中的 window.JS.postMessage(...)
..addJavaScriptChannel('JS', onMessageReceived: (dynamic message) {
// message 是动态对象,不在签名中引用具体类型以避免 "Undefined class" 问题
String payload;
try {
payload = message.message ?? message.toString();
} catch (e) {
payload = message.toString();
}
_onJsMessage(payload);
})
// 也保留一个备用通道 'Flutter'
..addJavaScriptChannel('Flutter', onMessageReceived: (dynamic message) {
String payload;
try {
payload = message.message ?? message.toString();
} catch (e) {
payload = message.toString();
}
_onJsMessage(payload);
})
..setNavigationDelegate(
NavigationDelegate(
onPageFinished: (String url) async {
2025-08-22 09:02:35 +08:00
LoadingDialogHelper.hide();
debugPrint('网页加载完成: $url');
await _injectLocationParams();
},
onWebResourceError: (err) {
debugPrint('Web resource error: ${err.description}');
},
),
);
// 加载本地 assets 中的 HTML
// await _controller.loadFlutterAsset('assets/map/test_baidu_map.html');
await _controller.loadRequest(Uri.parse('http://47.92.102.56:7811/file/fluteightmap/index.html'));
setState(() {
_isLoading = false;
});
} catch (e, st) {
debugPrint('获取位置或初始化失败: $e\n$st');
if (!mounted) return;
setState(() {
_errorMessage = '获取位置失败: ${e.toString()}';
_isLoading = false;
});
}
}
/// 注入参数并调用页面初始化函数 window.initWithData(...)
Future<void> _injectLocationParams() async {
if (_longitude == null || _latitude == null) {
debugPrint('位置尚未准备好,跳过注入');
return;
}
final params = {
'longitude': _longitude,
'latitude': _latitude,
'GSON': _gsonList,
't': DateTime.now().millisecondsSinceEpoch,
};
final jsonParams = jsonEncode(params);
try {
await _controller.runJavaScript('''
(function(){
try {
if (typeof window.initWithData === 'function') {
window.initWithData($jsonParams);
} else if (typeof window.initMap === 'function') {
window.initMap($jsonParams);
} else {
console.error('initWithData / initMap function not found');
}
} catch(e) {
console.error('call initWithData error', e);
}
})();
''');
debugPrint('已注入地图初始化参数');
} catch (e) {
debugPrint('注入位置参数失败: $e');
}
}
/// 处理来自 Web 的消息(字符串或 JSON
void _onJsMessage(String message) {
debugPrint('收到来自 Web 的消息: $message');
if (message.isEmpty) return;
try {
Map<String,dynamic> data = jsonDecode(message);
if (FormUtils.hasValue(data, 'ok') && data['ok'] == true) {
}else{
if (FormUtils.hasValue(data, 'type') && data['type'] == 'converted') {
setState(() {
mapData = data;
});
}else{
ToastUtil.showNormal(context, '当前选择点位不在区域中');
setState(() {
mapData = {};
});
}
}
} catch (_) {
setState(() {
mapData = {};
});
ToastUtil.showNormal(context, '当前选择点位不在区域中');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: MyAppbar(title: '地图选择', actions: [
if (mapData.isNotEmpty)
TextButton(onPressed: (){
Navigator.of(context).pop((mapData));
}, child: Text('确定', style: TextStyle(color: Colors.white, fontSize: 17),))
],),
body: SafeArea(
child: BaiduMapWebView(
controller: _isLoading || _errorMessage != null ? null : _controller,
isLoading: _isLoading,
errorMessage: _errorMessage,
onRetry: _initLocation,
),),
);
}
}