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

Flutter WebView控制器问题:底部导航切换URL失效求助

问题原因分析
  1. WebViewController未正确获取:你的WebViewContainer是无状态组件,且没有将内部的WebViewController暴露给父组件,导致controller变量始终为null,调用loadRequest自然无效。
  2. URL转换错误:直接将字符串强转为Uri会报错,应该用Uri.parse()方法转换。
  3. 导航项与URL列表不匹配:底部导航只有2个选项,但你需要4个,同时webViewList只有3个URL,数量不对应。
修正方案

1. 修改web_view_container.dart

将无状态组件改为有状态组件,并通过回调将WebViewController传递给父组件:

import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';

class WebViewContainer extends StatefulWidget {
  final String initialUrl;
  final Function(WebViewController controller) onControllerCreated;

  const WebViewContainer({
    required this.initialUrl,
    required this.onControllerCreated,
    super.key,
  });

  @override
  State<WebViewContainer> createState() => _WebViewContainerState();
}

class _WebViewContainerState extends State<WebViewContainer> {
  late WebViewController _controller;

  @override
  void initState() {
    super.initState();
    _controller = WebViewController()
      ..setJavaScriptMode(JavaScriptMode.unrestricted)
      ..loadRequest(Uri.parse(widget.initialUrl));
    widget.onControllerCreated(_controller);
  }

  @override
  Widget build(BuildContext context) {
    return WebViewWidget(controller: _controller);
  }
}

2. 修改main.dart

更新导航项、URL列表,正确获取并使用WebViewController:

import 'package:flutter/material.dart';
import 'package:vertbaudet_webview/web_view_container.dart';
import 'package:webview_flutter/web_view_flutter.dart';

void main() => runApp(
      MaterialApp(
        debugShowCheckedModeBanner: false,
        home: const WebViewExample(),
      ),
    );

class WebViewExample extends StatefulWidget {
  const WebViewExample({super.key});

  @override
  _WebViewExampleState createState() => _WebViewExampleState();
}

class _WebViewExampleState extends State<WebViewExample> {
  int selectedIndex = 0;
  final List<String> webViewList = [
    "https://google.com",
    "https://yahoo.com",
    "https://baidu.com",
    "https://www.vertbaudet.fr/", // 第四个URL,对应第四个导航项
  ];
  WebViewController? controller;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      bottomNavigationBar: BottomNavigationBar(
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: Icon(Icons.home),
            label: "首页",
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.business),
            label: "示例",
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.search),
            label: "搜索",
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.shopping_cart),
            label: "商城",
          ),
        ],
        currentIndex: selectedIndex,
        selectedItemColor: Colors.cyan,
        onTap: (i) {
          setState(() {
            selectedIndex = i;
          });
          // 使用正确的Uri转换方式加载URL
          controller?.loadRequest(Uri.parse(webViewList[i]));
        },
      ),
      appBar: AppBar(
        backgroundColor: const Color.fromRGBO(255, 255, 255, 1),
        toolbarHeight: 5,
        elevation: 0,
      ),
      body: WebViewContainer(
        initialUrl: webViewList[selectedIndex],
        onControllerCreated: (WebViewController c) {
          controller = c;
        },
      ),
    );
  }
}
关键改动说明
  • 将WebViewContainer改为有状态组件,在initState中初始化WebViewController,并通过回调传递给父组件。
  • 修正了URL转换方式,使用Uri.parse()替代错误的强转。
  • 补充了第四个底部导航项和对应的URL,满足你4个选项的需求。
  • 移除了无用的路由配置,直接将WebViewExample设为首页。

内容的提问来源于stack exchange,提问作者Disinq

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 01:37:13