逐行解读 Flutter 默认模板:从 `main()` 到计数器 App

逐行解读 Flutter 默认模板

  • [从 `main()` 到计数器 App](#从 main() 到计数器 App)
    • [🧩 一、程序入口:`main()` 与 `runApp()`](#🧩 一、程序入口:main()runApp())
    • [🏛️ 二、根组件:`MyApp`(无状态 Widget)](#🏛️ 二、根组件:MyApp(无状态 Widget))
    • [🔁 三、首页组件:`MyHomePage`(有状态 Widget)](#🔁 三、首页组件:MyHomePage(有状态 Widget))
      • [为什么需要 `StatefulWidget`?](#为什么需要 StatefulWidget?)
    • [🧠 四、状态逻辑:`_MyHomePageState`](#🧠 四、状态逻辑:_MyHomePageState)
    • [🔍 五、热重载 vs 热重启](#🔍 五、热重载 vs 热重启)
    • [✅ 六、总结:这份代码教会了我们什么?](#✅ 六、总结:这份代码教会了我们什么?)
    • [🚀 下一步建议](#🚀 下一步建议)

main() 到计数器 App

当你运行 flutter create 命令创建新项目时,Flutter 会自动生成一个经典的"计数器"示例应用。这段代码看似简单,却浓缩了 Flutter 开发的核心概念:入口函数、Widget 树、状态管理、热重载机制等。

本文将带你逐行解读这份默认代码,帮助你真正理解每一部分的作用,为后续深入学习打下坚实基础。


🧩 一、程序入口:main()runApp()

dart 复制代码
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}
  • import 'package:flutter/material.dart';

    引入 Flutter 的 Material Design 组件库(Google 官方设计语言),包含 ScaffoldAppBarTextButton 等常用 Widget。

  • void main()

    Dart 程序的入口函数,就像 C 或 Java 中的 main

  • runApp(const MyApp());

    MyApp 这个 Widget 作为根节点挂载到屏幕上。

    💡 所有 Flutter 应用都是由 Widget 构成的树形结构,runApp() 启动这棵树的渲染。


🏛️ 二、根组件:MyApp(无状态 Widget)

dart 复制代码
class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  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)

dart 复制代码
class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});
  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

为什么需要 StatefulWidget

因为这个页面包含一个会变化的计数器 _counter,需要在用户点击按钮时更新 UI。

  • final String title;

    接收父组件(MyApp)传入的标题,final 表示不可变。

  • createState()

    返回一个 State 对象(即 _MyHomePageState),状态实际存储在这里

📌 Flutter 中,状态(State)和 UI 描述(Widget)是分离的。Widget 是配置,State 才是数据。


🧠 四、状态逻辑:_MyHomePageState

dart 复制代码
class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  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 模式
热重载开发体验 修改代码即时生效,不丢失状态

🚀 下一步建议

  1. 动手修改:尝试添加"减一"按钮,或把计数器改成倒计时。
  2. 观察 rebuild :在 build() 方法开头加 print('Rebuilding...'),看看何时被调用。
  3. 探索 DevTools :运行 flutter run --profile 并打开 DevTools,查看 Widget 树和性能分析。

这个小小的计数器 App,是你通往复杂 Flutter 应用的第一步。理解它,你就已经掌握了 Flutter 的灵魂。

相关推荐
passerby60612 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了2 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅2 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
执笔论英雄2 小时前
【大模型学习cuda】入们第一个例子-向量和
学习
wdfk_prog3 小时前
[Linux]学习笔记系列 -- [drivers][input]input
linux·笔记·学习
崔庆才丨静觅3 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
renke33643 小时前
Flutter for OpenHarmony:色彩捕手——基于HSL色轮与感知色差的交互式色觉训练系统
flutter
崔庆才丨静觅3 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment3 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅4 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端