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

Flutter中HTML frame等效功能的实现方法

Flutter中实现类HTML frame布局的方案

Flutter没有和HTML frame完全等价的原生标签,但你要的侧边纵向导航+独立区域加载对应内容的效果,实现逻辑非常直接,和frame的行为逻辑完全一致。

核心实现逻辑

本质就是拆分固定导航区和独立内容区两个区块,点击导航项时只更新内容区的渲染结果,不触发导航区重建,完全匹配frame的交互效果:

  • 根布局用Row实现左右分栏,左侧固定宽度放导航列表,右侧剩余空间作为内容展示容器
  • 用状态变量记录当前选中的导航项
  • 点击导航项时,仅更新内容容器内加载的内容,左侧导航状态同步高亮即可

不同场景的实现选择

  • 如果右侧需要加载HTML页面内容:直接在右侧内容区嵌入webview_flutter提供的WebView组件,点击导航时调用WebView的加载方法传入对应页面地址即可,效果和iframe加载独立页面完全一致
  • 如果右侧加载的是Flutter原生页面:直接根据当前选中的导航下标,切换内容区对应的Flutter组件即可,不需要引入第三方依赖,渲染性能远高于HTML frame

最简可运行示例

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

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

  @override
  State<FrameLikePage> createState() => _FrameLikePageState();
}

class _FrameLikePageState extends State<FrameLikePage> {
  int _currentNavIndex = 0;
  // 替换成你实际需要加载的页面地址/组件配置
  final List<_NavItem> _navItems = [
    _NavItem(title: '1.html', pagePath: '/page1'),
    _NavItem(title: '2.html', pagePath: '/page2'),
    _NavItem(title: '3.html', pagePath: '/page3'),
  ];
  late final WebViewController _webController;

  @override
  void initState() {
    super.initState();
    _webController = WebViewController()
      ..loadRequest(Uri.parse(_navItems[_currentNavIndex].pagePath));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Row(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          // 左侧导航区
          SizedBox(
            width: 180,
            child: ListView.builder(
              itemCount: _navItems.length,
              itemBuilder: (context, index) {
                final item = _navItems[index];
                return ListTile(
                  title: Text(item.title),
                  selected: _currentNavIndex == index,
                  onTap: () {
                    if (_currentNavIndex == index) return;
                    setState(() {
                      _currentNavIndex = index;
                    });
                    _webController.loadRequest(Uri.parse(item.pagePath));
                  },
                );
              },
            ),
          ),
          const VerticalDivider(width: 1),
          // 右侧独立内容区
          Expanded(
            child: WebViewWidget(controller: _webController),
          )
        ],
      ),
    );
  }
}

class _NavItem {
  final String title;
  final String pagePath;
  _NavItem({required this.title, required this.pagePath});
}

如果需要适配移动端,也可以把左侧导航换成抽屉布局,核心逻辑不变,只需要调整外层布局容器即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 10:27:22