Flutter 组件层级关系

文章目录

前言

上一篇我们迎来了 Flutter 第一个项目,代码已经出现了几个常用组件 MaterialAppScaffold ,我们再多认识一个Container(类似html中的 div,万金油般的存在),它们是三个不同层级和用途的 Widget

dart 复制代码
...
    @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,

        title: Text(widget.title),
      ),
      body: Container(
        width: 100,
        height: 100,
        color: Colors.blue,
        margin: EdgeInsets.all(10),
        padding: EdgeInsets.all(20),
        child: Text('内容'),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }
 ...

MaterialApp - 应用级根组件

dart 复制代码
MaterialApp(
  title: 'My App',
  home: MyHomePage(),
  theme: ThemeData(primarySwatch: Colors.blue),
)
  • 层级最高:通常是整个应用的入口 Widget
  • 功能:
    • 提供 Material Design 应用框架
    • 管理应用级的配置(路由、主题、本地化等)
    • 包裹整个应用的内容
    • 提供 Navigator 用于页面导航

Scaffold - 页面骨架

dart 复制代码
Scaffold(
  appBar: AppBar(title: Text('主页')),
  body: Container(color: Colors.red),
  drawer: Drawer(),
  floatingActionButton: FloatingActionButton(onPressed: () {}),
)
  • 层级居中:通常作为单个页面的容器
  • 功能:
    • 提供 Material Design 页面的基本布局结构
    • 包含 appBar、body、drawer、bottomNavigationBar 等标准区域
    • 处理状态栏、键盘遮挡等系统交互

Container - 通用布局容器

dart 复制代码
Container(
  width: 100,
  height: 100,
  color: Colors.blue,
  margin: EdgeInsets.all(10),
  padding: EdgeInsets.all(20),
  child: Text('内容'),
)
  • 层级最低:用于布局和样式的通用容器
  • 功能:
    • 控制子 Widget 的尺寸、间距、对齐等
    • 可以设置装饰(颜色、边框、阴影等)
    • 非常灵活,几乎可以包裹任何 Widget

关系对比

特性 MaterialApp Scaffold Container
层级 最高(应用级) 中间(页面级) 最低(组件级)
用途 应用框架 页面骨架 布局容器
Material Design 必需 可选 无关
包含关系 包含 Scaffold 包含 Container 被包含
典型使用 应用入口 页面结构 布局控制

典型嵌套结构

dart 复制代码
void main() {
  runApp(
    MaterialApp(          // 1. 应用框架
      home: Scaffold(     // 2. 页面骨架
        body: Container(  // 3. 布局容器
          child: Text('Hello World'),
        ),
      ),
    ),
  );
}

简单记忆:MaterialApp 是整本书,Scaffold 是书中的一页,Container 是页面上的一个段落框。

页面数量与组件关系

dart 复制代码
void main() {
  runApp(
    MaterialApp(                    // ← 只有一个
      home: HomePage(),            // ← 第一个页面
      routes: {
        '/detail': (context) => DetailPage(),  // ← 第二个页面
        '/profile': (context) => ProfilePage(), // ← 第三个页面
      },
    ),
  );
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(              // ← 第一个 Scaffold
      body: Container(            // ← 第一个页面的 Container
        child: Text('首页'),
      ),
    );
  }
}

class DetailPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(              // ← 第二个 Scaffold
      body: Container(            // ← 第二个页面的 Container
        child: Text('详情页'),
      ),
    );
  }
}

数量对比

组件 数量 说明
MaterialApp 1个 整个应用只需要一个
Scaffold 每个页面一个 每个独立页面通常有自己的 Scaffold
Container N个 每个页面中可能有多个 Container

典型多页面结构

dart 复制代码
MaterialApp (1个)
├── HomePage (页面1)
│   ├── Scaffold (第1个)
│   │   ├── Container (可能多个)
│   │   ├── Container
│   │   └── ...
│   └── ...
├── DetailPage (页面2)
│   ├── Scaffold (第2个)
│   │   ├── Container (可能多个)
│   │   └── ...
│   └── ...
└── ProfilePage (页面3)
    ├── Scaffold (第3个)
    │   ├── Container (可能多个)
    │   └── ...
    └── ...

实际场景示例

MaterialApp 的独特性

dart 复制代码
// 整个应用只有一个 MaterialApp
void main() {
  runApp(
    MaterialApp(  // ← 这是唯一的 MaterialApp
      title: '多页面应用',
      initialRoute: '/',
      routes: {
        '/': (context) => HomePage(),
        '/list': (context) => ListPage(),
        '/detail': (context) => DetailPage(),
      },
    ),
  );
}

每个页面的 Scaffold

dart 复制代码
class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(  // ← HomePage 的 Scaffold
      appBar: AppBar(title: Text('首页')),
      body: Center(child: Text('首页内容')),
    );
  }
}

class ListPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(  // ← ListPage 的 Scaffold
      appBar: AppBar(title: Text('列表页')),
      body: ListView.builder(itemBuilder: ...),
    );
  }
}

Container 的数量不确定性

dart 复制代码
class DetailPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          Container(  // ← 第1个 Container
            padding: EdgeInsets.all(16),
            child: Text('标题'),
          ),
          Container(  // ← 第2个 Container
            margin: EdgeInsets.all(8),
            child: Image.network('...'),
          ),
          Container(  // ← 第3个 Container
            padding: EdgeInsets.all(16),
            child: Text('描述'),
          ),
        ],
      ),
    );
  }
}

重要注意事项

  1. MaterialApp 必须唯一

    • 整个应用只能有一个 MaterialApp
    • 如果需要嵌套(如在一个应用中嵌入另一个应用),应使用 WidgetsApp
  2. Scaffold 通常每页一个

    • 大多数页面使用一个 Scaffold 作为根
    • 但也可以没有 Scaffold(如全屏对话框、透明页面)
  3. Container 随意使用

    • 一个页面中可以有任意数量的 Container
    • 甚至可以嵌套多个 Container

总结

组件 数量规律 比喻
MaterialApp 唯一(整个应用1个) 整栋大楼的建筑图纸
Scaffold 每个页面通常1个 每个房间的框架结构
Container 任意数量(一个页面多个) 房间里的各种家具/箱子

这种设计让 Flutter 保持了清晰的层级关系:一个应用框架(MaterialApp)管理多个页面结构(Scaffold),每个页面中包含多个布局容器(Container)。

相关推荐
一起养小猫2 小时前
Flutter for OpenHarmony 实战:打地鼠游戏完整开发指南
flutter·游戏·harmonyos
梵得儿SHI2 小时前
Vue 高级特性:渲染函数与 JSX 精讲(h 函数语法、JSX 在 Vue 中的应用)
前端·javascript·vue.js·jsx·模板语法·渲染函数·底层视图生成机制
GGGG寄了2 小时前
CSS——文字控制属性
前端·javascript·css·html
菜鸟茜2 小时前
ES6核心知识解析01:什么是ES6以及为什么需要ES6
前端·javascript·es6
C澒2 小时前
FE BLL 架构:前端复杂业务的逻辑治理方案
前端·架构·前端框架·状态模式
一起养小猫2 小时前
Flutter for OpenHarmony 实战:打地鼠游戏难度设计与平衡性
flutter·游戏·harmonyos
ujainu2 小时前
Flutter + OpenHarmony 实战:构建独立可复用的皮肤选择界面
flutter·游戏·openharmony
Betelgeuse762 小时前
【Flutter For OpenHarmony】 阶段复盘:从单页Demo到模块化App
flutter·ui·华为·交互·harmonyos
止观止2 小时前
拒绝“都是 string”:品牌类型与领域驱动设计 (DDD)
前端·typescript