Files
tuiche/lib/component/tool/WebViewWidget.dart
2025-05-13 11:59:04 +08:00

79 lines
2.1 KiB
Dart

import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:url_launcher/url_launcher.dart';
class MyWebView extends StatefulWidget {
final String url;
final Function()? onLoad;
final Function(MyWebView view, String msg)? onMessage;
const MyWebView({
Key? key,
required this.url,
this.onLoad,
this.onMessage,
}) : super(key: key);
@override
State<MyWebView> createState() => _MyWebViewState();
}
class _MyWebViewState extends State<MyWebView> {
late final WebViewController _controller;
@override
void initState() {
super.initState();
_controller = WebViewController()
..setJavaScriptMode(JavaScriptMode.unrestricted)
..setNavigationDelegate(
NavigationDelegate(
onPageFinished: (url) {
widget.onLoad?.call();
},
onWebResourceError: (error) {
print("WebView 加载错误: ${error.description}");
},
onNavigationRequest: (NavigationRequest request) {
final url = request.url;
if (url.startsWith('http') || url.startsWith('https')) {
return NavigationDecision.navigate;
}
if (url.startsWith('weixin://')) {
_launchWeChatUrl(url);
return NavigationDecision.prevent;
}
print('拦截未知协议: $url');
return NavigationDecision.prevent;
},
),
)
..addJavaScriptChannel(
'FlutterChannel',
onMessageReceived: (msg) {
widget.onMessage?.call(widget, msg.message);
},
)
..loadRequest(Uri.parse(widget.url));
}
void _launchWeChatUrl(String url) async {
final uri = Uri.parse(url);
if (await canLaunchUrl(uri)) {
await launchUrl(uri);
} else {
print('⚠️ 无法跳转微信: $url');
}
}
// 提供方法给外部调用 JS
void sendData(String data) {
_controller.runJavaScript("window.postMessage('$data')");
}
@override
Widget build(BuildContext context) {
return WebViewWidget(controller: _controller);
}
}