01-Flutter入门指南

摘要:本文是Flutter初学者的完整入门指南,涵盖环境搭建、Dart语言基础、核心概念、常用组件、布局系统和实战案例。通过本文档,你将掌握Flutter开发的基础知识,能够独立开发简单的移动应用。

关键词:Flutter、Dart、移动开发、跨平台、Widget、状态管理、前端开发

适合人群:零基础初学者、有其他语言基础的开发者、想学习跨平台开发的工程师

阅读时间:约 60 分钟

版本信息:Flutter 3.x | Dart 3.x | 支持 Android/iOS/Web

更新日期:2026-09-03


文章目录

  • [1. Flutter 简介](#1. Flutter 简介)
    • [1.1 什么是 Flutter](#1.1 什么是 Flutter)
    • [1.2 为什么选择 Flutter](#1.2 为什么选择 Flutter)
    • [1.3 Flutter 架构](#1.3 Flutter 架构)
  • [2. 环境搭建](#2. 环境搭建)
    • [2.1 安装 Flutter SDK](#2.1 安装 Flutter SDK)
    • [2.2 配置开发工具](#2.2 配置开发工具)
    • [2.3 创建第一个项目](#2.3 创建第一个项目)
    • [2.4 运行项目](#2.4 运行项目)
  • [3. Dart 语言基础](#3. Dart 语言基础)
    • [3.1 变量与数据类型](#3.1 变量与数据类型)
    • [3.2 函数](#3.2 函数)
    • [3.3 控制流](#3.3 控制流)
    • [3.4 类与对象](#3.4 类与对象)
    • [3.5 异步编程](#3.5 异步编程)
  • [4. Flutter 核心概念](#4. Flutter 核心概念)
    • [4.1 Widget 简介](#4.1 Widget 简介)
    • [4.2 StatelessWidget](#4.2 StatelessWidget)
    • [4.3 StatefulWidget](#4.3 StatefulWidget)
    • [4.4 生命周期](#4.4 生命周期)
  • [5. 常用组件](#5. 常用组件)
    • [5.1 基础组件](#5.1 基础组件)
    • [Text 文本组件](#Text 文本组件)
    • [Image 图片组件](#Image 图片组件)
    • [Icon 图标组件](#Icon 图标组件)
    • [5.2 按钮组件](#5.2 按钮组件)
    • [ElevatedButton 凸起按钮](#ElevatedButton 凸起按钮)
    • [TextButton 文字按钮](#TextButton 文字按钮)
    • [IconButton 图标按钮](#IconButton 图标按钮)
    • [FloatingActionButton 浮动操作按钮](#FloatingActionButton 浮动操作按钮)
    • [5.3 输入组件](#5.3 输入组件)
    • [TextField 文本输入框](#TextField 文本输入框)
    • 密码输入框
    • [5.4 列表组件](#5.4 列表组件)
    • [ListView 基础列表](#ListView 基础列表)
    • [ListView.builder 动态列表](#ListView.builder 动态列表)
  • [6. 布局系统](#6. 布局系统)
    • [6.1 Row 与 Column](#6.1 Row 与 Column)
    • [Row 水平布局](#Row 水平布局)
    • [Column 垂直布局](#Column 垂直布局)
    • [6.2 Container 容器组件](#6.2 Container 容器组件)
    • [6.3 Stack 层叠布局](#6.3 Stack 层叠布局)
    • [6.4 Padding 与 Margin](#6.4 Padding 与 Margin)
  • [7. 状态管理基础](#7. 状态管理基础)
    • [7.1 setState 基础用法](#7.1 setState 基础用法)
    • [7.2 状态提升](#7.2 状态提升)
  • [💡 综合实战案例](#💡 综合实战案例)
    • [待办事项应用(Todo App)](#待办事项应用(Todo App))
  • [❓ 常见问题 FAQ](#❓ 常见问题 FAQ)
    • [1. Flutter 和 React Native 有什么区别?](#1. Flutter 和 React Native 有什么区别?)
    • [2. 热重载和热重启有什么区别?](#2. 热重载和热重启有什么区别?)
    • [3. 为什么 setState 没有生效?](#3. 为什么 setState 没有生效?)
    • [4. 如何调试 Flutter 应用?](#4. 如何调试 Flutter 应用?)
    • [5. 如何添加第三方依赖包?](#5. 如何添加第三方依赖包?)
    • [6. 如何处理屏幕适配?](#6. 如何处理屏幕适配?)
  • [📝 总结](#📝 总结)
  • [📚 参考资料](#📚 参考资料)

1. Flutter 简介

1.1 什么是 Flutter

Flutter 是 Google 推出的开源 UI 软件开发工具包,用于构建跨平台的移动、Web 和桌面应用。

核心特点

  • 🚀 跨平台:一套代码,多端运行(Android、iOS、Web、Windows、macOS、Linux)
  • 高性能:使用自研 Skia 图形引擎,直接编译为原生机器码
  • 🎨 丰富的组件:内置大量 Material Design 和 Cupertino 风格组件
  • 🔥 热重载:修改代码后毫秒级刷新,无需重启应用

💡 提示:Flutter 使用 Dart 语言开发,Dart 是一种类型安全、支持异步编程的现代语言。

1.2 为什么选择 Flutter

特性 Flutter React Native 原生开发
性能 ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐⭐
开发效率 ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐
UI 一致性 ⭐⭐⭐⭐⭐ ⭐⭐⭐ ⭐⭐⭐⭐⭐
学习曲线 ⭐⭐⭐⭐ ⭐⭐⭐ ⭐⭐
社区生态 ⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐

1.3 Flutter 架构

Flutter 采用分层架构,从下到上依次为:

  1. Embedder:平台适配层,负责与操作系统交互

  2. Engine:核心引擎,包含 Skia 图形库、Dart 运行时等

  3. Framework:应用框架层,包含 Widget、渲染、动画等

    ┌─────────────────┐
    │ Your App │ ← 你的代码
    ├─────────────────┤
    │ Framework │ ← Widget、Material/Cupertino
    ├─────────────────┤
    │ Engine │ ← Skia、Dart Runtime
    ├─────────────────┤
    │ Embedder │ ← Android/iOS/Web
    └─────────────────┘


2. 环境搭建

2.1 安装 Flutter SDK

Windows 系统

  1. 下载 Flutter SDK:https://flutter.dev/docs/get-started/install
  2. 解压到指定目录(如 C:\flutter
  3. C:\flutter\bin 添加到系统环境变量 PATH
  4. 打开命令行,运行以下命令验证安装:
bash 复制代码
flutter doctor

💡 提示flutter doctor 会检查环境配置,根据提示安装缺失的依赖。

2.2 配置开发工具

推荐工具:VS Code 或 Android Studio

VS Code 配置

  1. 安装 VS Code
  2. 安装 Flutter 和 Dart 插件
  3. 重启 VS Code

Android Studio 配置

  1. 安装 Android Studio
  2. 安装 Flutter 插件(会自动安装 Dart 插件)
  3. 配置 Android SDK

2.3 创建第一个项目

在命令行中运行:

bash 复制代码
flutter create my_first_app
cd my_first_app

项目结构

复制代码
my_first_app/
├── android/          # Android 平台代码
├── ios/              # iOS 平台代码
├── lib/              # Dart 源代码(主要工作目录)
│   └── main.dart     # 应用入口
├── test/             # 测试代码
├── pubspec.yaml      # 项目配置和依赖
└── README.md

2.4 运行项目

连接设备后运行

bash 复制代码
# 查看可用设备
flutter devices

# 运行项目
flutter run

# 热重载(运行中按 r)
# 热重启(运行中按 R)
# 退出(运行中按 q)

💡 提示:如果没有真机,可以使用模拟器或 Chrome 浏览器运行:

bash 复制代码
flutter run -d chrome

3. Dart 语言基础

3.1 变量与数据类型

Dart 是强类型语言,支持类型推断。

dart 复制代码
// 变量声明
String name = 'Flutter';
int age = 25;
double height = 175.5;
bool isStudent = true;

// 类型推断(推荐)
var city = '北京';  // 自动推断为 String
final pi = 3.14;    // 编译时常量
const gravity = 9.8; // 编译时常量(更高效)

// 可空类型(Dart 3.x)
String? nickname = null;  // 可以为 null
String username = 'admin'; // 不能为 null

// 集合类型
List<String> fruits = ['苹果', '香蕉', '橙子'];
Map<String, int> scores = {'数学': 90, '英语': 85};
Set<int> uniqueNumbers = {1, 2, 3, 4, 5};

效果说明

  • var 让编译器自动推断类型
  • final 运行时常量,赋值后不可修改
  • const 编译时常量,性能更优
  • ? 表示该变量可以为 null(可空类型)

3.2 函数

dart 复制代码
// 基础函数
String greet(String name) {
  return 'Hello, $name!';
}

// 箭头函数(单行表达式)
String greetShort(String name) => 'Hello, $name!';

// 可选参数
void printInfo(String name, {int? age, String? city}) {
  print('姓名: $name, 年龄: $age, 城市: $city');
}

// 位置可选参数
void printColors(String primary, [String? secondary]) {
  print('主色: $primary, 副色: $secondary');
}

// 调用示例
printInfo('张三', age: 25, city: '北京');
printColors('红色', '蓝色');

效果说明

  • {} 包裹命名可选参数,调用时需指定参数名
  • [] 包裹位置可选参数,调用时按顺序传递
  • ? 表示参数可以为 null

3.3 控制流

dart 复制代码
// if-else
int score = 85;
if (score >= 90) {
  print('优秀');
} else if (score >= 60) {
  print('及格');
} else {
  print('不及格');
}

// for 循环
for (int i = 0; i < 5; i++) {
  print(i);
}

// for-in 循环(遍历集合)
List<String> fruits = ['苹果', '香蕉', '橙子'];
for (var fruit in fruits) {
  print(fruit);
}

// while 循环
int count = 0;
while (count < 3) {
  print(count);
  count++;
}

// switch-case
String day = 'Monday';
switch (day) {
  case 'Monday':
    print('周一');
    break;
  case 'Tuesday':
    print('周二');
    break;
  default:
    print('其他');
}

3.4 类与对象

dart 复制代码
// 定义类
class Person {
  String name;
  int age;
  
  // 构造函数
  Person(this.name, this.age);
  
  // 命名构造函数
  Person.unknown() : name = '未知', age = 0;
  
  // 方法
  void introduce() {
    print('我叫$name,今年$age岁');
  }
}

// 使用类
void main() {
  var person = Person('张三', 25);
  person.introduce();
  
  var unknown = Person.unknown();
  unknown.introduce();
}

效果说明

  • this.name 是 Dart 的语法糖,自动赋值
  • 命名构造函数提供更灵活的初始化方式
  • Dart 支持单继承,但可以实现多个接口

3.5 异步编程

Flutter 大量使用异步编程处理网络请求、文件读写等操作。

dart 复制代码
// Future 表示未来的值
Future<String> fetchData() async {
  // 模拟网络请求
  await Future.delayed(Duration(seconds: 2));
  return '数据加载完成';
}

// 使用 async/await
void loadData() async {
  print('开始加载...');
  String result = await fetchData();
  print(result);
}

// 错误处理
void loadDataWithError() async {
  try {
    String result = await fetchData();
    print(result);
  } catch (e) {
    print('加载失败: $e');
  }
}

效果说明

  • Future<T> 表示一个未来会返回 T 类型值的异步操作
  • async 标记函数为异步函数
  • await 等待异步操作完成
  • try-catch 捕获异步操作中的异常

4. Flutter 核心概念

4.1 Widget 简介

在 Flutter 中,一切皆 Widget(组件)。

Widget 是 Flutter 应用 UI 的基本构建块,包括:

  • 按钮、文本、图片等可见元素
  • 布局容器(Row、Column、Stack)
  • 样式、动画、手势处理等

Widget 分类

类型 特点 使用场景
StatelessWidget 不可变,无状态 静态内容、展示型组件
StatefulWidget 可变,有状态 交互型组件、动态内容

4.2 StatelessWidget

用于不需要改变状态的静态内容。

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

class MyHomePage extends StatelessWidget {
  const MyHomePage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('我的第一个应用'),
      ),
      body: const Center(
        child: Text('Hello, Flutter!'),
      ),
    );
  }
}

效果说明

  • Scaffold 是 Material Design 的页面结构,包含 appBar、body 等
  • Center 将子组件居中显示
  • const 表示编译时常量,提升性能

4.3 StatefulWidget

用于需要响应交互或数据变化的动态内容。

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

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

  @override
  State<CounterWidget> createState() => _CounterWidgetState();
}

class _CounterWidgetState extends State<CounterWidget> {
  int _counter = 0;

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

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Text('点击次数: $_counter'),
        ElevatedButton(
          onPressed: _increment,
          child: const Text('点击+1'),
        ),
      ],
    );
  }
}

效果说明

  • StatefulWidget 需要创建对应的 State
  • setState() 通知 Flutter 状态已改变,需要重新构建 UI
  • _counter 前的下划线表示私有变量(Dart 命名规则)

4.4 生命周期

StatefulWidget 的生命周期方法:

dart 复制代码
class _MyWidgetState extends State<MyWidget> {
  @override
  void initState() {
    super.initState();
    // 组件初始化时调用(只调用一次)
    print('initState: 组件创建');
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    // 依赖改变时调用
    print('didChangeDependencies');
  }

  @override
  void didUpdateWidget(MyWidget oldWidget) {
    super.didUpdateWidget(oldWidget);
    // 父组件重建时调用
    print('didUpdateWidget');
  }

  @override
  void dispose() {
    // 组件销毁时调用(只调用一次)
    print('dispose: 组件销毁');
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    // 每次状态改变都会调用
    return Container();
  }
}

生命周期流程图

复制代码
创建: initState → didChangeDependencies → build
更新: didUpdateWidget → build
销毁: dispose

5. 常用组件

5.1 基础组件

Text 文本组件

dart 复制代码
// 基础文本
const Text('Hello Flutter')

// 带样式文本
Text(
  'Flutter 教程',
  style: TextStyle(
    fontSize: 24,
    fontWeight: FontWeight.bold,
    color: Colors.blue,
  ),
)

// 多行文本
Text(
  '这是一段很长的文本,可能会超出屏幕宽度,需要换行显示。',
  maxLines: 2,
  overflow: TextOverflow.ellipsis,
)

效果说明

  • maxLines 限制最大行数
  • overflow: TextOverflow.ellipsis 超出时显示省略号

Image 图片组件

dart 复制代码
// 网络图片
Image.network('https://example.com/image.jpg')

// 本地资源图片(需放在 assets 目录)
Image.asset('assets/images/logo.png')

// 带圆角的图片
ClipRRect(
  borderRadius: BorderRadius.circular(10),
  child: Image.network('https://example.com/avatar.jpg'),
)

Icon 图标组件

dart 复制代码
const Icon(Icons.home, size: 30, color: Colors.blue)
const Icon(Icons.favorite, color: Colors.red)

5.2 按钮组件

ElevatedButton 凸起按钮

dart 复制代码
ElevatedButton(
  onPressed: () {
    print('按钮被点击');
  },
  child: const Text('点击我'),
)

TextButton 文字按钮

dart 复制代码
TextButton(
  onPressed: () {},
  child: const Text('了解更多'),
)

IconButton 图标按钮

dart 复制代码
IconButton(
  icon: const Icon(Icons.add),
  onPressed: () {},
)

FloatingActionButton 浮动操作按钮

dart 复制代码
FloatingActionButton(
  onPressed: () {},
  child: const Icon(Icons.add),
)

5.3 输入组件

TextField 文本输入框

dart 复制代码
TextField(
  decoration: const InputDecoration(
    labelText: '请输入用户名',
    border: OutlineInputBorder(),
    prefixIcon: Icon(Icons.person),
  ),
  onChanged: (value) {
    print('输入内容: $value');
  },
)

效果说明

  • decoration 设置输入框的装饰样式
  • labelText 显示提示标签
  • onChanged 监听输入内容变化

密码输入框

dart 复制代码
TextField(
  obscureText: true,  // 隐藏输入内容
  decoration: const InputDecoration(
    labelText: '请输入密码',
    border: OutlineInputBorder(),
  ),
)

5.4 列表组件

ListView 基础列表

dart 复制代码
ListView(
  children: [
    ListTile(
      leading: const Icon(Icons.home),
      title: const Text('首页'),
      onTap: () => print('点击首页'),
    ),
    ListTile(
      leading: const Icon(Icons.settings),
      title: const Text('设置'),
      onTap: () => print('点击设置'),
    ),
  ],
)

ListView.builder 动态列表

适用于大量数据的列表,按需渲染。

dart 复制代码
ListView.builder(
  itemCount: 100,
  itemBuilder: (context, index) {
    return ListTile(
      title: Text('列表项 $index'),
    );
  },
)

效果说明

  • itemCount 指定列表项总数
  • itemBuilder 按需创建列表项,性能优于普通 ListView
  • 适合数据量超过屏幕显示范围的场景

6. 布局系统

6.1 Row 与 Column

Row 水平布局

dart 复制代码
Row(
  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
  children: [
    Container(color: Colors.red, width: 50, height: 50),
    Container(color: Colors.blue, width: 50, height: 50),
    Container(color: Colors.green, width: 50, height: 50),
  ],
)

效果说明

  • mainAxisAlignment 控制主轴(水平方向)对齐方式
  • 可选值:startendcenterspaceBetweenspaceAroundspaceEvenly

Column 垂直布局

dart 复制代码
Column(
  crossAxisAlignment: CrossAxisAlignment.start,
  children: [
    const Text('标题', style: TextStyle(fontSize: 20)),
    const Text('副标题'),
    const Text('内容描述'),
  ],
)

效果说明

  • crossAxisAlignment 控制交叉轴(水平方向)对齐方式
  • start 表示左对齐,center 表示居中,end 表示右对齐

6.2 Container 容器组件

Container 是最常用的布局组件,支持设置尺寸、颜色、边距等。

dart 复制代码
Container(
  width: 200,
  height: 100,
  margin: const EdgeInsets.all(16),
  padding: const EdgeInsets.all(8),
  decoration: BoxDecoration(
    color: Colors.blue,
    borderRadius: BorderRadius.circular(10),
    boxShadow: [
      BoxShadow(
        color: Colors.black26,
        blurRadius: 10,
        offset: const Offset(0, 5),
      ),
    ],
  ),
  child: const Text(
    'Container 示例',
    style: TextStyle(color: Colors.white),
  ),
)

效果说明

  • margin 外边距,控制容器与其他组件的间距
  • padding 内边距,控制容器与子组件的间距
  • decoration 装饰器,设置背景色、圆角、阴影等

6.3 Stack 层叠布局

Stack 允许子组件堆叠显示,类似 CSS 的 position: absolute。

dart 复制代码
Stack(
  alignment: Alignment.center,
  children: [
    Container(
      width: 200,
      height: 200,
      color: Colors.blue,
    ),
    const Positioned(
      top: 10,
      right: 10,
      child: Icon(Icons.close, color: Colors.white),
    ),
    const Text(
      '层叠内容',
      style: TextStyle(color: Colors.white, fontSize: 20),
    ),
  ],
)

效果说明

  • alignment 控制未定位子组件的对齐方式
  • Positioned 精确控制子组件位置(top、bottom、left、right)
  • 后面的子组件会覆盖前面的子组件

6.4 Padding 与 Margin

dart 复制代码
// Padding 内边距
Padding(
  padding: const EdgeInsets.all(16.0),
  child: const Text('带内边距的文本'),
)

// Container 的 margin 外边距
Container(
  margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
  child: const Text('带外边距的文本'),
)

EdgeInsets 常用方法

  • EdgeInsets.all(value):四个方向相同
  • EdgeInsets.symmetric(horizontal: h, vertical: v):水平/垂直对称
  • EdgeInsets.only(left: l, top: t, right: r, bottom: b):单独设置

7. 状态管理基础

7.1 setState 基础用法

setState 是 Flutter 最基础的状态管理方式。

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

  @override
  State<CounterPage> createState() => _CounterPageState();
}

class _CounterPageState extends State<CounterPage> {
  int _count = 0;
  String _message = '点击按钮开始计数';

  void _incrementCounter() {
    setState(() {
      _count++;
      _message = '当前计数: $_count';
    });
  }

  void _resetCounter() {
    setState(() {
      _count = 0;
      _message = '计数器已重置';
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('计数器')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(_message, style: const TextStyle(fontSize: 20)),
            const SizedBox(height: 20),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                ElevatedButton(
                  onPressed: _incrementCounter,
                  child: const Text('+1'),
                ),
                const SizedBox(width: 20),
                ElevatedButton(
                  onPressed: _resetCounter,
                  child: const Text('重置'),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

效果说明

  • setState 包裹需要更新的状态变量
  • 调用 setState 后会触发 build 方法重新执行
  • 适合简单的页面级状态管理

7.2 状态提升

当多个组件需要共享状态时,将状态提升到父组件。

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

  @override
  State<ParentWidget> createState() => _ParentWidgetState();
}

class _ParentWidgetState extends State<ParentWidget> {
  bool _isSelected = false;

  void _toggleSelection() {
    setState(() {
      _isSelected = !_isSelected;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        ChildWidget(
          isSelected: _isSelected,
          onToggle: _toggleSelection,
        ),
        Text(_isSelected ? '已选中' : '未选中'),
      ],
    );
  }
}

class ChildWidget extends StatelessWidget {
  final bool isSelected;
  final VoidCallback onToggle;

  const ChildWidget({
    super.key,
    required this.isSelected,
    required this.onToggle,
  });

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: onToggle,
      child: Text(isSelected ? '取消选中' : '选中'),
    );
  }
}

效果说明

  • 状态保存在父组件中,通过参数传递给子组件
  • 子组件通过回调函数通知父组件更新状态
  • 这是 Flutter 推荐的状态管理模式

💡 综合实战案例

待办事项应用(Todo App)

结合前面所学知识,实现一个完整的待办事项应用。

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

void main() {
  runApp(const TodoApp());
}

class TodoApp extends StatelessWidget {
  const TodoApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: '待办事项',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        useMaterial3: true,
      ),
      home: const TodoListPage(),
    );
  }
}

class TodoItem {
  String title;
  bool isDone;

  TodoItem({required this.title, this.isDone = false});
}

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

  @override
  State<TodoListPage> createState() => _TodoListPageState();
}

class _TodoListPageState extends State<TodoListPage> {
  final List<TodoItem> _todos = [];
  final TextEditingController _controller = TextEditingController();

  void _addTodo() {
    if (_controller.text.trim().isNotEmpty) {
      setState(() {
        _todos.add(TodoItem(title: _controller.text.trim()));
        _controller.clear();
      });
    }
  }

  void _toggleTodo(int index) {
    setState(() {
      _todos[index].isDone = !_todos[index].isDone;
    });
  }

  void _deleteTodo(int index) {
    setState(() {
      _todos.removeAt(index);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('待办事项'),
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
      ),
      body: Column(
        children: [
          // 输入区域
          Padding(
            padding: const EdgeInsets.all(16.0),
            child: Row(
              children: [
                Expanded(
                  child: TextField(
                    controller: _controller,
                    decoration: const InputDecoration(
                      labelText: '输入待办事项',
                      border: OutlineInputBorder(),
                    ),
                    onSubmitted: (_) => _addTodo(),
                  ),
                ),
                const SizedBox(width: 8),
                ElevatedButton(
                  onPressed: _addTodo,
                  child: const Text('添加'),
                ),
              ],
            ),
          ),
          // 列表区域
          Expanded(
            child: _todos.isEmpty
                ? const Center(child: Text('暂无待办事项'))
                : ListView.builder(
                    itemCount: _todos.length,
                    itemBuilder: (context, index) {
                      final todo = _todos[index];
                      return ListTile(
                        leading: Checkbox(
                          value: todo.isDone,
                          onChanged: (_) => _toggleTodo(index),
                        ),
                        title: Text(
                          todo.title,
                          style: TextStyle(
                            decoration: todo.isDone
                                ? TextDecoration.lineThrough
                                : null,
                            color: todo.isDone ? Colors.grey : Colors.black,
                          ),
                        ),
                        trailing: IconButton(
                          icon: const Icon(Icons.delete, color: Colors.red),
                          onPressed: () => _deleteTodo(index),
                        ),
                      );
                    },
                  ),
          ),
        ],
      ),
    );
  }
}

效果说明

  • 使用 TextField 输入待办事项
  • 使用 ListView.builder 展示待办列表
  • 使用 Checkbox 标记完成状态
  • 使用 IconButton 删除待办事项
  • 完成的事项显示删除线效果

❓ 常见问题 FAQ

1. Flutter 和 React Native 有什么区别?

解答

  • 渲染方式:Flutter 使用自绘引擎(Skia),RN 使用原生组件
  • 性能:Flutter 直接编译为机器码,性能更接近原生
  • UI 一致性:Flutter 自带组件库,各平台表现一致;RN 依赖原生组件
  • 学习成本:Flutter 学 Dart 语言,RN 学 React 思想

2. 热重载和热重启有什么区别?

解答

  • 热重载(r):保留应用状态,快速刷新 UI 变更
  • 热重启(R):重新编译整个应用,状态会丢失
  • 使用场景:修改 UI 用热重载,修改逻辑代码用热重启

3. 为什么 setState 没有生效?

解答

常见原因:

  1. 忘记调用 setState() 方法
  2. setState 外部修改了状态
  3. 使用了 const 组件,无法重建
dart 复制代码
// 错误写法
_counter++;  // 没有通知 Flutter

// 正确写法
setState(() {
  _counter++;  // 在 setState 内部修改
});

4. 如何调试 Flutter 应用?

解答

  • print 调试 :使用 print() 打印日志
  • DevTools :运行 flutter pub global activate devtools,然后 flutter pub global run devtools
  • 断点调试:在 VS Code 或 Android Studio 中设置断点
  • Inspector:使用 Flutter Inspector 查看 Widget 树

5. 如何添加第三方依赖包?

解答

  1. pubspec.yaml 中添加依赖:
yaml 复制代码
dependencies:
  flutter:
    sdk: flutter
  http: ^1.1.0
  provider: ^6.1.0
  1. 运行命令安装:
bash 复制代码
flutter pub get
  1. 在代码中导入使用:
dart 复制代码
import 'package:http/http.dart' as http;

6. 如何处理屏幕适配?

解答

  • MediaQuery:获取屏幕尺寸
dart 复制代码
final screenWidth = MediaQuery.of(context).size.width;
  • LayoutBuilder:根据父组件尺寸布局
dart 复制代码
LayoutBuilder(
  builder: (context, constraints) {
    return Container(width: constraints.maxWidth / 2);
  },
)
  • Expanded/Flexible:自动填充剩余空间

📝 总结

本文介绍了 Flutter 开发的基础知识,涵盖以下核心内容:

知识点回顾

模块 核心内容 重要程度
Dart 语言 变量、函数、类、异步编程 ⭐⭐⭐⭐⭐
Widget StatelessWidget、StatefulWidget ⭐⭐⭐⭐⭐
常用组件 Text、Button、TextField、ListView ⭐⭐⭐⭐⭐
布局系统 Row、Column、Container、Stack ⭐⭐⭐⭐⭐
状态管理 setState、状态提升 ⭐⭐⭐⭐

学习建议

  1. 先理解概念:Widget 树、状态管理是核心
  2. 多写代码:动手实践比只看文档更有效
  3. 善用文档:官方文档 https://flutter.dev 是最权威的学习资源
  4. 从小项目开始:先做简单的应用,逐步增加复杂度

下一步学习

  • 路由与导航(Navigator)
  • 网络请求(http 包)
  • 状态管理进阶(Provider、Riverpod、Bloc)
  • 本地存储(SharedPreferences、SQLite)
  • 动画与过渡效果

📚 参考资料

📚 系列导航入门指南 | 进阶开发 | 状态管理 | 网络与存储 | 实战项目

相关推荐
lqj_本人12 小时前
Flutter 三方库「flutter_ble_peripheral」的鸿蒙化适配指南
flutter·华为·harmonyos
lqj_本人13 小时前
Flutter 三方库「flutter-dualscreen」的鸿蒙化适配指南
flutter·华为·harmonyos
●VON16 小时前
鸿蒙跨平台框架怎么选?从真实需求比较 Flutter、React Native、KMP/CMP 与 Web 路线
flutter·react native·harmonyos
lqj_本人17 小时前
Flutter 三方库「flutter_displaymode」的鸿蒙化适配指南
flutter·华为·harmonyos
lqj_本人20 小时前
Flutter 三方库「drag_and_drop_flutter」的鸿蒙化适配指南
flutter·华为·harmonyos
天空之城--1 天前
Flutter 三棵树:原理、机制与最佳实践
flutter
天空之城--1 天前
Flutter线程模型完全指南:从架构到实战
flutter·架构
天空之城--1 天前
Flutter底层原理深度解析
flutter
安好说AI2 天前
Flutter 三方库 adaptive_image_picker 的鸿蒙化适配指南:零权限选图、纯 Dart 裁剪与目标大小压缩
flutter·harmonyos