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

Flutter结合底部标签栏实现多WebView及Android端切换不加载问题咨询

Flutter多WebView切换不加载问题解决方案

问题根因

  • 你当前把3个WebView定义为static const类型的静态列表,Flutter会将其识别为不可变常量,切换标签时不会触发WebView实例的重建
  • Android端webview_flutter插件存在默认的实例复用逻辑,没有唯一标识区分不同WebView的情况下,只会保留首个加载的WebView内容,导致切换标签后页面不更新

修复方案(两种可选)

方案1:动态生成WebView(实现简单,每次切换重新加载页面)

直接移除静态WebView列表,根据选中索引动态生成带唯一Key的WebView实例,修改后的核心代码如下:

class _MyStatefulWidgetState extends State<MyStatefulWidget> {
  int _selectedIndex = 0;

  // 改为存储URL列表,不要预定义WebView实例
  static const List<String> _urlOptions = <String>[
    'https://www.google.com/',
    'https://www.apple.com/',
    'https://www.microsoft.com/',
  ];

  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Image.asset('assets/logo.png', fit: BoxFit.cover,  height: 32,),
        backgroundColor: Color.fromRGBO(121, 186, 56,1)
      ),
      // 动态生成带唯一Key的WebView
      body: Center(
        child: WebView(
          key: ValueKey(_urlOptions[_selectedIndex]), // 唯一Key强制重建
          initialUrl: _urlOptions[_selectedIndex],
          javascriptMode: JavascriptMode.unrestricted,
        ),
      ),
      bottomNavigationBar: BottomNavigationBar(
        backgroundColor: Color.fromRGBO(121, 186, 56,1),
        selectedItemColor: Colors.black,
        unselectedItemColor: Colors.white,
        items: const <BottomNavigationBarItem >[
          BottomNavigationBarItem(
            icon: Icon(Icons.home),
            label: 'Home',
            backgroundColor: Colors.blue,
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.favorite),
            label: 'Tips',
            backgroundColor: Colors.green,
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.calendar_today),
            label: 'Online Form',
            backgroundColor: Colors.pink,
          ),
        ],
        currentIndex: _selectedIndex,
        onTap: _onItemTapped,
      ),
    );
  }
}

方案2:IndexedStack保活(切换无需重新加载,保留页面操作状态)

如果需要切换标签后保留WebView的浏览状态,不用重新加载页面,改用IndexedStack包裹所有WebView,同时给每个WebView添加唯一Key:

class _MyStatefulWidgetState extends State<MyStatefulWidget> {
  int _selectedIndex = 0;

  // 定义带唯一Key的WebView列表,不要加const修饰
  late List<Widget> _widgetOptions;

  @override
  void initState() {
    super.initState();
    _widgetOptions = <Widget>[
      WebView(
        key: ValueKey("google"),
        initialUrl: 'https://www.google.com/',
        javascriptMode: JavascriptMode.unrestricted,
      ),
      WebView(
        key: ValueKey("apple"),
        initialUrl: 'https://www.apple.com/',
        javascriptMode: JavascriptMode.unrestricted,
      ),
      WebView(
        key: ValueKey("microsoft"),
        initialUrl: 'https://www.microsoft.com/',
        javascriptMode: JavascriptMode.unrestricted,
      ),
    ];
  }

  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Image.asset('assets/logo.png', fit: BoxFit.cover,  height: 32,),
        backgroundColor: Color.fromRGBO(121, 186, 56,1)
      ),
      // 用IndexedStack保活所有子页面
      body: IndexedStack(
        index: _selectedIndex,
        children: _widgetOptions,
      ),
      bottomNavigationBar: BottomNavigationBar(
        backgroundColor: Color.fromRGBO(121, 186, 56,1),
        selectedItemColor: Colors.black,
        unselectedItemColor: Colors.white,
        items: const <BottomNavigationBarItem >[
          BottomNavigationBarItem(
            icon: Icon(Icons.home),
            label: 'Home',
            backgroundColor: Colors.blue,
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.favorite),
            label: 'Tips',
            backgroundColor: Colors.green,
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.calendar_today),
            label: 'Online Form',
            backgroundColor: Colors.pink,
          ),
        ],
        currentIndex: _selectedIndex,
        onTap: _onItemTapped,
      ),
    );
  }
}

额外注意事项

  • 需确保Android端android/app/src/main/AndroidManifest.xml中已经添加了网络权限:<uses-permission android:name="android.permission.INTERNET"/>
  • 如果使用的是webview_flutter 4.0以上版本,API有小幅调整,可根据官方文档对应修改初始化参数即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 07:54:04