引用:
flutter常用的三方库
Flutter基础(二)--App结构和生命周期
Flutter 网络请求深度解析
Flutter 项目常用插件库推荐(2025 最新版)

- dart:是一种面向对象语言,dart是flutter的程序开发语言。
- main函数:是程序运行的入口函数
-
runApp函数:是渲染根widget树的函数
一般情况下runApp函数会在main函数里执行
语言的主要特点是什么?
- 面向对象:支持类和单继承
- 强类型:但支持类型推断
- 异步编程:内置 Future 和 Stream 支持
- 空安全:支持非空类型检查
- JIT 和 AOT:支持即时编译和提前编译
widget
widget在flutter里基本是一些UI组件
有两种类型的widget:
statefulWidget:会自己重新构建自己(可以改变状态,通过 setState() 触发重建)
statelessWidget:不可变,一旦创建就不能改变
布局Widget:Container、Row、Column、Stack等。
常用Widget:Text、Image、ListView、GridView等。
StatefulWidget:通过setState管理状态。
状态管理方案:Provider、Riverpod、Bloc、GetX等状态管理工具。
Flutter 中的生命周期
- StatelessWidget:
build() - StatefulWidget:
创建/初始化:createState()、initState()
依赖:didChangeDependencies()
构建:build()「每次父Widget重新构建时都会调用此方法,setState 调用?」
更新:didUpdateWidget()
失活:deactivate() 「当应用从后台切换到前台时」
清理:dispose() 「清理资源、取消订阅、关闭流等」
| 生命周期方法 | 调用时机 | 典型用途 |
|---|---|---|
createState |
StatefulWidget 创建时,框架会调用此方法创建 State 对象。 | 返回 State 实例。 |
initState |
State 对象被插入 Widget 树时仅调用一次。 | 初始化数据、订阅 Stream、创建动画控制器、监听事件。 |
didChangeDependencies |
initState 之后立即调用;当该 State 对象的依赖发生变化时(如 InheritedWidget 更新)。 |
依赖 InheritedWidget 的场景,比如主题、语言变化时的响应。 |
build |
每次构建 Widget 树时都会调用(可能被频繁调用)。 | 必须返回一个 Widget 树,不要在此执行耗时操作。 |
didUpdateWidget |
父组件重建导致当前 Widget 的配置发生变化时。 | 响应父组件传下来的 widget 属性变化,如 oldWidget 比较。 |
setState |
开发者手动调用,通知框架数据变化。 | 更新 UI 数据,触发 build 重新执行。 |
deactivate |
State 对象从 Widget 树中被移除时(可能被重新插入)。 | 清理与当前树位置相关的临时资源。 |
dispose |
State 对象永久从 Widget 树中移除时仅调用一次。 | 取消订阅、停止动画、销毁控制器、释放资源(必须!)。 |

状态管理
Flutter 中有哪些状态管理方案?
基础方案:setState
中级方案:InheritedWidget、Provider
高级方案:Riverpod、BLC、Redux、MobX、GetX
Provider 的工作原理是什么?
Provider 是基于 InheritedWidget 的封装,它允许在 Widget 树中高效地共享数据。当数据变化时,只有依赖该数据的 Widget 会重建。
什么是 BLC 模式?
BLC (Business Logic Component) 是一种状态管理模式,它将业务逻辑与 UI 分离,使用 Stream 和 Sink 来处理数据流。
什么是 BuildContext?
BuildContext 是 Widget 在树中位置的句柄(上下文联系的桥梁),用于:
- 查找父 Widget 或主题
- 导航 (Navigator.of(context))
- 显示对话框等
Hot Reload 和 Hot Restart 有什么区别吗?
Hot Reload比Hot Restart快
Hot Reload:[热重载],局部刷新,会编译我们文件里新加的代码并发送给dart虚拟机,dart会更新widgets来改变UI,会保留之前的state。
Hot Restart:[热重启] 重新启动整个应用。Hot Restart会重置所有的state回到初始值。
异步编程:理解Stream,掌握async和await。
包管理:学习如何使用pubspec.yaml管理依赖。
Stream
Stream 用来处理连续的异步操作,Stream 是一个抽象类,用于表示一序列异步数据的源。它是一种产生连续事件的方式,可以生成数据事件或者错误事件,以及流结束时的完成事件
Stream 分单订阅流和广播流。
网络状态的监控
Dart 中的 final 和 const 有什么区别?
- const:编译时常量,必须在编译时就知道值
-
final:运行时常量,只能赋值一次
布局与样式
常见的布局 Widget 有哪些?
Container:通用容器,可设置 padding/margin/decoration
Row/Column:水平和垂直布局
Stack:重叠布局
ListView/GridView:滚动列表
Flex/Expanded:弹性布局
如何实现响应式布局?
使用 MediaQuery.of(context) 获取屏幕尺寸
使用 LayoutBuilder 获取约束条件
使用 Flexible 和 Expanded 弹性布局
使用百分比或弹性布局
使用 OrientationBuilder 处理横竖屏变化
什么是 Theme?
Theme 是 Flutter 中统一管理应用样式的方式,可以定义颜色、字体、按钮样式等,并在整个应用中保持一致。
路由与导航
如何在 Flutter 中实现导航?
'//导航到新页面'
Navigator.push(context, MaterialPageRoute(builder: (context) => NewPage()));
'//返回上一页'
Navigator.pop(context);
命名路由如何配置?
MaterialApp(
routes: {
'/': (context) => HomePage(),
'/details': (context) => DetailsPage(),
},
);
解释 Dart 中的异步编程
Dart 使用 Future 和 async/await 处理异步操作:
Future<String> fetchData() async {
var response = await http.get('https://api.example.com/data');
return response.body;
}
网络与存储
如何进行网络请求?使用 http 包:
var response = await http.get(Uri.parse('https://api.example.com/data'));
三方库:dio
Flutter 中的数据存储选项有哪些?
SharedPreferences:简单的键值对存储
SQLite:关系型数据库 (使用 sqflite 包)
Hive:轻量级 NoSQL 数据库
Firebase:云存储解决方案
性能优化
1. 如何优化 Flutter 应用性能?
使用 const Widget 减少重建
避免在 build 方法中进行耗时操作
使用 ListView.builder 处理长列表
减少 Widget 树的深度
使用性能分析工具 (Flutter DevTools)
2. 什么是 Widget 重建?如何避免不必要的重建?
Widget 重建是 Flutter 响应状态变化的机制。避免不必要重建的方法:
使用 const 构造函数
将不常变化的部分拆分为独立的 Widget
使用 Provider 等状态管理工具精确控制重建范围
常见的陷阱问题
Q1:setState 一定会触发 build 吗?
是的,setState 会标记当前 State 为 dirty,在下一帧强制重新执行 build。
Q2:initState 中能否访问 context?
可以访问,但不能进行依赖 InheritedWidget 的操作(因为 didChangeDependencies 还未调用)。如果需要,使用 WidgetsBinding.instance.addPostFrameCallback。
Q3:dispose 中调用 setState 会怎样?
会报错:setState() called after dispose()。必须在调用前检查 mounted 属性。
if (mounted) {
setState(() {});
}
Q4:Hot Reload 会触发哪些生命周期?
只触发 build 和 didUpdateWidget(如果 widget 类型变化),不会触发 initState 和 dispose。
| 场景 | 正确做法 |
|---|---|
| 启动网络请求 | 在 initState 中异步发起,在 dispose 中取消。 |
| 监听滚动、主题变化 | 在 initState 订阅,在 dispose 取消。 |
| 动画控制器 | 在 initState 创建,在 dispose 销毁。 |
| 页面可见性(前后台) | 使用 WidgetsBindingObserver 监听。 |
| 页面跳转时的资源清理 | 使用 RouteAware 监听路由生命周期。 |
initState 类似 iOS中的 Viewdidload?
| 特性 | Flutter initState
|
iOS viewDidLoad
|
|---|---|---|
| 调用时机 | State 对象被插入 Widget 树时(仅一次) | 视图控制器加载视图完成后(仅一次) |
| 核心用途 | 初始化数据、配置监听、准备资源 | 初始化数据、配置 UI、准备资源 |
| 视图/UI 状态 | 此时 context 可用,但 UI 尚未构建完成 |
此时 view 已加载,但尚未显示到屏幕 |
| 典型操作 | 启动网络请求、添加监听、创建动画控制器 | 启动网络请求、添加通知、设置按钮点击事件 |
| 视图重建时 | ❌ 重建时不调用(如主题切换、旋转屏幕) | ✅ 重新调用(如内存警告后重建) |
| UI 状态 | ❌ UI 尚未构建 | ✅ UI 已经加载完成 |
| 能操作 UI 吗 | 不能直接操作 UI 组件(因为还没创建) | 可以操作 UI 组件(如设置按钮文字) |
| 对象分配 | createState |
init |
| 初始化和资源配置 | initState |
viewDidLoad |
| 依赖准备就绪 | didChangeDependencies |
viewWillAppear |
更准确的对应关系:
-
initState≈init的一部分 +viewDidLoad:用于初始化数据、配置资源,但不能操作 UI。 -
didChangeDependencies≈viewWillAppear:此时依赖已就绪,可以安全访问主题、Provider 等。 -
build≈viewDidLayoutSubviews+ 绘制:构建实际界面。
代码对比
// Flutter
@override
void initState() {
super.initState();
_loadData(); // 启动网络请求
_addListener(); // 添加监听
_initController(); // 初始化控制器
}
// iOS
override func viewDidLoad() {
super.viewDidLoad()
loadData() // 启动网络请求
addNotification() // 添加通知
setupUI() // 初始化 UI 组件
}
Flutter 应用如何打包发布?
'//Android:'
flutter build appbundle
或
flutter build apk
//'iOS'
flutter build ios