Flutter 中的状态管理
如何使用 ChangeNotifier 管理状态的说明。
学习使用 ChangeNotifier 创建 ViewModel,并管理加载、成功与错误状态。
你将完成的内容
步骤
1
介绍
介绍
当开发者在 Flutter 中谈论状态管理时,他们本质上指的是应用更新正确渲染所需数据,然后通知 Flutter 用新数据重新渲染 UI 的模式。
在 MVVM 中,这一职责落在 ViewModel 层,它位于 UI 与 Model 层之间并连接两者。在 Flutter 中,ViewModel 使用 Flutter 的 ChangeNotifier 类在数据变化时通知 UI。
要使用 ChangeNotifier,在你的状态管理类中继承它以获得 notifyListeners() 方法的访问权限,调用该方法时会触发 UI 重建。
2
创建基本 view model 结构
创建基本 view model 结构
创建 ArticleViewModel 类及其基本结构与状态属性:
class ArticleViewModel extends ChangeNotifier {
final ArticleModel model;
Summary? summary;
Exception? error;
bool isLoading = false;
ArticleViewModel(this.model);
}
ArticleViewModel 保存三份状态:
-
summary:当前的 Wikipedia 文章数据。 -
error:数据获取过程中发生的任何错误。 -
isLoading:用于显示进度指示器的标志。
3
添加构造函数初始化
添加构造函数初始化
更新构造函数,以便在创建 ArticleViewModel 时自动获取内容:
class ArticleViewModel extends ChangeNotifier {
final ArticleModel model;
Summary? summary;
Exception? error;
bool isLoading = false;
ArticleViewModel(this.model) {
fetchArticle();
}
// Methods will be added next.
Future<void> fetchArticle() async {}
}
此构造函数初始化在创建
ArticleViewModel 对象时即可提供内容。由于构造函数不能是异步的,它将初始内容获取委托给单独的方法。
4
设置 fetchArticle 方法
设置 fetchArticle 方法
添加用于获取数据并管理状态更新的 fetchArticle 方法:
class ArticleViewModel extends ChangeNotifier {
final ArticleModel model;
Summary? summary;
Exception? error;
bool isLoading = false;
ArticleViewModel(this.model) {
fetchArticle();
}
Future<void> fetchArticle() async {
isLoading = true;
notifyListeners();
// TODO: Add data fetching logic
isLoading = false;
notifyListeners();
}
}
ViewModel 会更新 isLoading 属性并调用 notifyListeners() 通知 UI 已更新。操作完成后,它会将该属性切换回来。构建 UI 时,你将使用此 isLoading 属性在获取新文章时显示加载指示器。
5
从 ArticleModel 获取文章
从 ArticleModel 获取文章
完善 fetchArticle 方法以获取文章摘要。使用 try-catch block
优雅地处理网络错误并保存 UI 可向用户显示的错误消息。该方法在成功时清除先前的错误,在出错时清除先前的文章摘要以保持一致的状态。
class ArticleViewModel extends ChangeNotifier {
final ArticleModel model;
Summary? summary;
Exception? error;
bool isLoading = false;
ArticleViewModel(this.model) {
fetchArticle();
}
Future<void> fetchArticle() async {
isLoading = true;
notifyListeners();
try {
summary = await model.getRandomArticleSummary();
error = null; // Clear any previous errors.
} on HttpException catch (e) {
error = e;
summary = null;
}
isLoading = false;
notifyListeners();
}
}
6
测试 ViewModel
测试 ViewModel
在构建完整 UI 之前,通过将结果打印到控制台来测试 HTTP 请求是否有效。首先,更新 fetchArticle 方法以打印结果:
Future<void> fetchArticle() async {
isLoading = true;
notifyListeners();
try {
summary = await model.getRandomArticleSummary();
print('Article loaded: ${summary!.titles.normalized}'); // Temporary
error = null; // Clear any previous errors.
} on HttpException catch (e) {
print('Error loading article: ${e.message}'); // Temporary
error = e;
summary = null;
}
isLoading = false;
notifyListeners();
}
然后,更新 MainApp widget 以创建 ArticleViewModel,它在创建时会调用 fetchArticle 方法:
class MainApp extends StatelessWidget {
const MainApp({super.key});
@override
Widget build(BuildContext context) {
// Instantiate your `ArticleViewModel` to test its HTTP requests.
final viewModel = ArticleViewModel(ArticleModel());
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('Wikipedia Flutter')),
body: const Center(child: Text('Check console for article data')),
),
);
}
}
热重载应用并查看控制台输出。你应看到文章标题或错误消息,这确认 Model 与 ViewModel 已正确连接。
7
回顾
回顾
你完成的内容
以下是你本课构建与学习内容的摘要。使用 ChangeNotifier 创建了 ArticleViewModel
ViewModel 位于 UI 与 Model 之间,管理状态并连接两层。通过继承 ChangeNotifier,ViewModel 获得在数据变化时通知监听者的能力。
管理了加载、成功与错误状态
ViewModel 跟踪三份状态: isLoading、summary 和 error。使用 try
和 catch,你优雅地处理网络错误并为每种可能结果保持一致的状态。
使用 notifyListeners 通知 UI 更新
调用 notifyListeners() 会告诉所有监听的 widget 重建。你在将 loading = true 之后调用一次,在操作完成后再调用一次。这就是在 Flutter 中实现响应式 UI 更新的方式。
8
自测
自测
状态管理测验
1 / 2-
向用户显示通知的 widget。
不正确。
ChangeNotifier 不是 widget;它是用于管理状态的类。
-
当数据变化时可通知监听者、从而实现响应式 UI 更新的类。
正确!
ChangeNotifier 提供 notifyListeners 方法,在状态变化时通知 widget 重建。
-
用于发送推送通知的内置 Dart 类。
不正确。
ChangeNotifier 用于应用内状态管理,而非推送通知。
-
Flutter 中的一种动画控制器类型。
不正确。
动画控制器是独立的;ChangeNotifier 用于状态管理。
notifyListeners() 会做什么?
-
将当前状态保存到本地存储。
不正确。
notifyListeners()通知 UI 更新;持久化需要单独实现。 -
告诉所有监听的 widget 重建并反映新状态。
正确!
调用
notifyListeners()会触发监听此 ChangeNotifier 的所有 widget 重建。 -
将状态变化记录到控制台以便调试。
不正确。
它不会记录任何内容;它通知监听者重建。
-
将所有状态属性重置为默认值。
不正确。
notifyListeners()不会修改状态;它只是表明状态已变化。
除非另有说明,本文档之所提及适用于 Flutter 3.44.0 版本。本页面最后更新时间:2026-06-18。查看文档源码 或者 为本页面内容提出建议。