You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:45:41