逐行解读 Flutter 默认模板:从 `main()` 到计数器 App
当你运行 `flutter create` 命令创建新项目时,Flutter 会自动生成一个经典的“计数器”示例应用。这段代码看似简单,却**浓缩了 Flutter 开发的核心概念**:入口函数、Widget 树、状态管理、热重载机制等。

-
个人首页: VON
-
鸿蒙系列专栏: 鸿蒙开发小型案例总结
-
综合案例 :鸿蒙综合案例开发
-
鸿蒙6.0:从0开始的开源鸿蒙6.0.0
-
鸿蒙5.0:鸿蒙5.0零基础入门到项目实战
-
Electron适配开源鸿蒙专栏:Electron for OpenHarmony
-
本文章所属专栏:Flutter for OpenHarmony
逐行解读 Flutter 默认模板

从 main() 到计数器 App
当你运行 flutter create 命令创建新项目时,Flutter 会自动生成一个经典的“计数器”示例应用。这段代码看似简单,却浓缩了 Flutter 开发的核心概念:入口函数、Widget 树、状态管理、热重载机制等。
本文将带你逐行解读这份默认代码,帮助你真正理解每一部分的作用,为后续深入学习打下坚实基础。
🧩 一、程序入口:main() 与 runApp()
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
-
import 'package:flutter/material.dart';
引入 Flutter 的 Material Design 组件库(Google 官方设计语言),包含Scaffold、AppBar、TextButton等常用 Widget。 -
void main()
Dart 程序的入口函数,就像 C 或 Java 中的main。 -
runApp(const MyApp());
将MyApp这个 Widget 作为根节点挂载到屏幕上。💡 所有 Flutter 应用都是由 Widget 构成的树形结构,
runApp()启动这棵树的渲染。
🏛️ 二、根组件:MyApp(无状态 Widget)
class MyApp extends StatelessWidget {
const MyApp({super.key});
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
关键点解析:
-
StatelessWidget
表示这个组件没有内部状态——一旦创建,UI 不会随数据变化而自动更新(适合静态内容)。 -
build()方法
每次需要渲染 UI 时都会调用此方法,返回一个 Widget 树。在这里,我们返回了MaterialApp。 -
MaterialApp
是整个应用的“容器”,提供:- 主题(
theme) - 路由管理(
home指定首页) - 导航栏样式等全局配置
- 主题(
-
ColorScheme.fromSeed(seedColor: Colors.deepPurple)
使用 Material 3 的配色系统,以deepPurple为种子色自动生成一套协调的主题色。
✅ 小实验:把
deepPurple改成Colors.green,保存后触发热重载(Hot Reload),你会发现整个 App 的主题色立刻变了,但计数器数字没重置——这就是热重载的魔力!
🔁 三、首页组件:MyHomePage(有状态 Widget)
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
State<MyHomePage> createState() => _MyHomePageState();
}
为什么需要 StatefulWidget?
因为这个页面包含一个会变化的计数器 _counter,需要在用户点击按钮时更新 UI。
-
final String title;
接收父组件(MyApp)传入的标题,final表示不可变。 -
createState()
返回一个State对象(即_MyHomePageState),状态实际存储在这里。
📌 Flutter 中,状态(State)和 UI 描述(Widget)是分离的。Widget 是配置,State 才是数据。
🧠 四、状态逻辑:_MyHomePageState
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text('You have pushed the button this many times:'),
Text(
'$_counter',
style: Theme.of(context).textTheme.headlineMedium,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
child: const Icon(Icons.add),
),
);
}
}
核心机制:setState()
_counter是状态变量,初始值为 0。- 当用户点击浮动按钮(
FloatingActionButton),会调用_incrementCounter()。 setState()是关键!
它告诉 Flutter:“我的状态变了,请重新调用build()方法刷新 UI。”
⚠️ 如果你直接写
_counter++而不调用setState(),UI 不会更新!因为 Flutter 不知道数据已变。
UI 结构解析:
Scaffold:提供标准的 Material 布局结构(AppBar + Body + FAB 等)。AppBar:顶部导航栏,标题来自widget.title(注意:通过widget访问父组件传入的属性)。Center+Column:将两个Text垂直居中排列。FloatingActionButton:右下角圆形按钮,点击触发_incrementCounter。
🔍 五、热重载 vs 热重启
代码中的注释特别强调了这一点:
“Notice that the counter didn’t reset back to zero; the application state is not lost during the reload.”
- 热重载(Hot Reload):
保留当前状态(如_counter = 5),只更新 UI 和代码逻辑。适合快速调试样式和逻辑。 - 热重启(Hot Restart,按
R):
重启整个应用,状态重置。用于测试初始化逻辑。
✅ 六、总结:这份代码教会了我们什么?
| 概念 | 在代码中的体现 |
|---|---|
| Widget 是一切 | 整个 App 由嵌套的 Widget 构成 |
| 声明式 UI | build() 方法描述“UI 应该是什么样子” |
| 状态驱动更新 | 通过 setState() 触发 UI 重建 |
| 状态与 UI 分离 | StatefulWidget + State 模式 |
| 热重载开发体验 | 修改代码即时生效,不丢失状态 |
🚀 下一步建议
- 动手修改:尝试添加“减一”按钮,或把计数器改成倒计时。
- 观察 rebuild:在
build()方法开头加print('Rebuilding...'),看看何时被调用。 - 探索 DevTools:运行
flutter run --profile并打开 DevTools,查看 Widget 树和性能分析。
这个小小的计数器 App,是你通往复杂 Flutter 应用的第一步。理解它,你就已经掌握了 Flutter 的灵魂。
更多推荐



所有评论(0)