随着移动互联网的发展,跨平台开发已经成为一个不可忽视的技术方向。本文将带领读者从零开始学习 Flutter,循序渐进地掌握这个强大的跨平台开发框架。截至 2024 年 12 月,Flutter 已经发展到了 3.27 版本。在学习和使用的过程中,我发现国内现在网上可以找到的 Flutter 相关文章教程等并不多,且很多都是比较过时的。因此,我计划从 2025 年开始,分享自己平时做的笔记以及工作上积累的经验,希望能对正在学习或使用 Flutter 的同学有所帮助。同时,我也希望通过写作来磨练自己的技术。由于技术写作经验有限,文中可能存在逻辑表达不清、字词错误、代码错误或格式错误等问题,欢迎读者在评论区或私信中指出,以便及时修正优化,非常感谢!
Flutter 是 Google 推出的一个开源 UI 工具包,它彻底改变了我们对跨平台开发的认知。不同于传统的跨平台框架,Flutter 采用了自绘引擎 Skia 图形引擎,不依赖原生控件,这使得它可以完全控制渲染流程,保证多平台 UI 一致性,并提供更好的动画性能表现。此外,Flutter 支持 AOT(Ahead Of Time)编译,直接编译成原生代码,从而实现启动速度快、运行时性能好、内存占用小等优点。同时,Flutter 还支持 iOS、Android、Web、Windows、macOS 和 Linux 等多个平台,并提供了亚秒级的热重载功能,大大提升了开发效率。
AOT 与 JIT 编译
Flutter 根据不同场景使用两种编译模式:
- AOT (Ahead Of Time) 编译 :在应用发布前将 Dart 代码预编译为本地机器码,主要用于 Release 模式下的生产环境发布。这种方式能保证运行性能好、无需运行时编译、启动速度快、内存占用小。
- JIT (Just In Time) 编译 :在运行时动态将 Dart 代码编译为机器码,主要用于 Debug 模式下的开发环境。它支持热重载(Hot Reload),方便调试和提高开发效率。
Flutter 巧妙地结合了这两种编译模式的优势:开发时使用 JIT 提供流畅的开发体验;发布时使用 AOT 确保最佳性能。
在众多跨平台方案中,Flutter 具有显著优势,包括但不限于:
特性 | Flutter | React Native | Uni-app |
---|---|---|---|
渲染引擎 | Skia 自绘引擎 | JSCore + 原生桥接 | V8/JSCore + WebView |
渲染性能 | 接近原生 | 接近原生(部分损耗) | 依赖浏览器 |
动画性能 | 60fps 稳定 | 部分场景丢帧 | 依赖设备性能 |
首屏加载 | 较快 | 需要 JS 引擎预热 | 需要 WebView 初始化 |
学习曲线 | 中等 | 较低(如熟悉 React) | 较低 |
生态系统 | 快速成长 | 成熟稳定 | 完善 |
热重载 | 支持 | 支持 | 支持 |
包大小 | 较大 | 较小 | 中等 |
使用场景 | 全平台应用 | 移动端应用为主 | 偏向小程序 |
中文社区 | 一般 | 活跃 | 活跃 |
开发语言 | Dart | JavaScript | JavaScript/Vue |
上手难度 | 中等 | 较易 | 较易 |
调试工具 | 完善 | 完善 | 一般 |
跨平台性 | 优秀 | 良好 | 优秀 |
# 创建开发目录
mkdir C:\src
cd C:\src
# 下载Flutter SDK
git clone https://github.com/flutter/flutter.git -b stable
# 添加Flutter到系统环境变量
setx PATH "%PATH%;C:\src\flutter\bin"
# 验证安装
flutter --version
# 检查环境变量是否生效
echo %PATH%
# 验证Flutter环境
flutter doctor -v
# 解决常见问题
flutter doctor --android-licenses
# 检查配置
flutter doctor
# 使用Homebrew安装
brew install --cask flutter
# 配置环境变量
# 添加到 ~/.zshrc 或 ~/.bash_profile
export PATH="$PATH:`pwd`/flutter/bin"
# iOS开发配置
sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
sudo xcodebuild -license
# 创建模拟器
flutter emulators --create
# 启动模拟器
flutter emulators --launch <emulator_id>
{
"editor.formatOnSave": true,
"editor.formatOnType": true,
"dart.previewFlutterUiGuides": true
}
在学习了 Flutter 的核心概念后,我们将创建一个待办事项应用来实践这些知识,包括使用 StatelessWidget 和 StatefulWidget 感受 Widget 生命周期管理、应用状态管理、处理用户输入、实现数据持久化等功能。
# 创建新项目
flutter create todo_list
# 进入项目目录
cd todo_list
# 运行项目
flutter run
todo_list/
├── android/ # Android平台相关代码
├── ios/ # iOS平台相关代码
├── lib/ # Flutter源代码
│ └── main.dart # 入口文件
├── test/ # 测试文件
└── pubspec.yaml # 项目配置文件
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
Widget build(BuildContext context) {
return MaterialApp(
title: 'Todo List',
theme: ThemeData(
primarySwatch: Colors.blue,
useMaterial3: true,
),
home: const TodoListPage(),
);
}
}
// lib/models/todo_item.dart
class TodoItem {
final String id;
final String title;
bool isCompleted;
TodoItem({
required this.id,
required this.title,
this.isCompleted = false,
});
// 用于JSON序列化
Map<String, dynamic> toJson() => {
'id': id,
'title': title,
'isCompleted': isCompleted,
};
// 从JSON创建实例
factory TodoItem.fromJson(Map<String, dynamic> json) => TodoItem(
id: json['id'],
title: json['title'],
isCompleted: json['isCompleted'],
);
}
// lib/main.dart
import 'package:flutter/material.dart';
import 'package:todo_list/models/todo_item.dart';
/// 应用程序入口点
void main() {
runApp(const MyApp());
}
/// 自定义无状态小部件,代表整个应用程序
class MyApp extends StatelessWidget {
/// 构造函数,接收一个可选的key参数
const MyApp({Key? key}) : super(key: key);
Widget build(BuildContext context) {
// 返回MaterialApp小部件,配置应用程序的基本设置
return MaterialApp(
title: 'Todo List', // 设置应用程序标题
theme: ThemeData(
primarySwatch: Colors.blue, // 设置主题颜色
useMaterial3: true, // 使用Material Design 3样式
),
home: const TodoListPage(), // 设置主页面为TodoListPage
);
}
}
/// 自定义有状态小部件,表示待办事项列表页面
class TodoListPage extends StatefulWidget {
/// 构造函数,接收一个可选的key参数
const TodoListPage({Key? key}) : super(key: key);
State<TodoListPage> createState() => _TodoListPageState();
}
/// 管理TodoListPage的状态
class _TodoListPageState extends State<TodoListPage> {
// 存储所有待办事项的列表
final List<TodoItem> _items = [];
// 创建一个文本控制器,用于管理输入框中的文本
final _textController = TextEditingController();
/// 添加新的待办事项
void _addTodoItem(String title) {
if (title.isEmpty) return; // 如果标题为空,则不添加
setState(() {
// 添加新的待办事项到列表中
_items.add(TodoItem(
id: DateTime.now().toString(), // 使用当前时间戳作为唯一标识符
title: title,
));
});
// 清空输入框
_textController.clear();
}
/// 切换待办事项的完成状态
void _toggleTodoItem(String id) {
setState(() {
// 查找并切换指定ID的待办事项的完成状态
final item = _items.firstWhere((item) => item.id == id);
item.isCompleted = !item.isCompleted;
});
}
/// 移除待办事项
void _removeTodoItem(String id) {
setState(() {
// 从列表中移除指定ID的待办事项
_items.removeWhere((item) => item.id == id);
});
}
Widget build(BuildContext context) {
// 返回Scaffold小部件,包含应用栏和主体内容
return Scaffold(
appBar: AppBar(
title: const Text('Todo List'), // 设置应用栏标题
),
body: Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
Expanded(
child: TextField(
controller: _textController, // 绑定文本控制器
decoration: const InputDecoration(
hintText: '添加新的待办事项', // 设置输入框提示文本
),
),
),
IconButton(
icon: const Icon(Icons.add), // 设置图标按钮的图标
onPressed: () => _addTodoItem(_textController.text), // 点击时调用添加方法
),
],
),
),
Expanded(
child: ListView.builder(
itemCount: _items.length, // 设置列表项数量
itemBuilder: (context, index) {
final item = _items[index];
return ListTile(
leading: Checkbox(
value: item.isCompleted, // 设置复选框的状态
onChanged: (_) => _toggleTodoItem(item.id), // 状态变化时调用切换方法
),
title: Text(
item.title, // 显示待办事项标题
style: TextStyle(
decoration: item.isCompleted
? TextDecoration.lineThrough // 完成的事项加删除线
: null,
),
),
trailing: IconButton(
icon: const Icon(Icons.delete), // 设置删除按钮的图标
onPressed: () => _removeTodoItem(item.id), // 点击时调用移除方法
),
);
},
),
),
],
),
);
}
void dispose() {
// 释放资源,确保没有内存泄漏
_textController.dispose();
super.dispose();
}
}
flutter_lints
保持代码风格一致,遵循 Effective Dart 指南,合理使用注释和文档字符串,保持代码模块化和可测试性。const
构造函数避免不必要的重建,合理使用StatefulWidget
,优化图片资源。studio64.exe.vmoptions
文件,增加内存至 4096m 或更多。export PUB_HOSTED_URL=https://pub.flutter-io.cn
export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn
xcrun simctl erase all
pubspec.yaml
中指定版本:dependencies:
package_name: ^x.y.z
在开发完 Flutter 应用后,发布到 iOS 平台是一个必不可少的步骤。为了简化这一过程,推荐使用 Appuploader,这是一款专为 iOS 开发者设计的工具,能够帮助开发者快速、高效地完成应用的打包、签名和上传到 App Store 的过程。
通过使用 Appuploader,开发者可以更加专注于应用的开发,而不必为繁琐的发布流程而烦恼。无论是个人开发者还是团队,Appuploader 都是一个值得信赖的工具。
本篇文章到这就差不多啦~ 如有疑问欢迎评论区讨论或者私信