Flutter中WebView无法加载不同URL问题求助
问题分析
你遇到的问题根源在于你使用的webview_flutter 0.3.13版本中,WebView的initialUrl参数仅在组件第一次初始化时生效。当你通过setState更新url变量后,虽然build方法重新执行了,但已经创建完成的WebView不会再读取新的initialUrl值,自然也就不会加载新的链接。
解决方案
这里有两种可行的解决方式,你可以根据实际需求选择:
方案一:使用GlobalKey强制重建WebView
通过给WebView设置可变的GlobalKey,当url变化时更新Key,让Flutter认为这是一个全新的WebView组件,从而重新初始化并加载新URL。
修改后的代码如下:
import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:webview_flutter/webview_flutter.dart'; void main() => runApp(WebPage()); class WebPage extends StatefulWidget { @override State<StatefulWidget> createState() { return _WebPageState(); } } class _WebPageState extends State<WebPage> { String url = "https://flutter.dev/"; // 定义GlobalKey,每次url变化时更新Key值 GlobalKey<WebViewState> _webViewKey = GlobalKey(); void _changeUrl() { setState(() { url = "https://github.com/flutter/flutter"; // 生成新的Key,强制WebView重建 _webViewKey = GlobalKey(); }); } @override Widget build(BuildContext context) { print("url:" + url); return MaterialApp( theme: ThemeData(primarySwatch: Colors.blue), home: Scaffold( appBar: AppBar(title: Text("WebPage")), body: WebView( key: _webViewKey, // 绑定Key initialUrl: url, javascriptMode: JavascriptMode.unrestricted, ), floatingActionButton: FloatingActionButton( onPressed: _changeUrl, child: Icon(Icons.replay), ), ), ); } }
⚠️ 注意:这种方式会完全重建WebView,之前的浏览历史、表单输入等状态都会丢失,适合简单场景使用。
方案二:使用WebViewController动态加载URL(推荐)
通过WebViewController直接控制WebView加载新链接,这种方式不会重建组件,能保留之前的页面状态,是更优的解决方案。
修改后的代码如下:
import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:webview_flutter/webview_flutter.dart'; void main() => runApp(WebPage()); class WebPage extends StatefulWidget { @override State<StatefulWidget> createState() { return _WebPageState(); } } class _WebPageState extends State<WebPage> { String url = "https://flutter.dev/"; WebViewController _webViewController; // 声明控制器 void _changeUrl() { final newUrl = "https://github.com/flutter/flutter"; // 通过控制器加载新URL _webViewController?.loadUrl(newUrl); // 可选:同步更新url变量,保持打印和显示一致 setState(() { url = newUrl; }); } @override Widget build(BuildContext context) { print("url:" + url); return MaterialApp( theme: ThemeData(primarySwatch: Colors.blue), home: Scaffold( appBar: AppBar(title: Text("WebPage")), body: WebView( initialUrl: url, javascriptMode: JavascriptMode.unrestricted, // 在WebView创建时获取控制器 onWebViewCreated: (controller) { _webViewController = controller; }, ), floatingActionButton: FloatingActionButton( onPressed: _changeUrl, child: Icon(Icons.replay), ), ), ); } }
这种方式直接调用loadUrl方法触发新链接的加载,既高效又能保留页面状态,推荐你优先使用这个方案。
内容的提问来源于stack exchange,提问作者Charles
相关产品推荐
相关产品推荐

