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 createState() => _MyWebViewState(); } class _MyWebViewState extends State { 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); } }