
个人首页: VON
鸿蒙系列专栏: 鸿蒙开发小型案例总结
综合案例 :鸿蒙综合案例开发
鸿蒙6.0:从0开始的开源鸿蒙6.0.0
鸿蒙5.0:鸿蒙5.0零基础入门到项目实战
Electron适配开源鸿蒙专栏:Electron for OpenHarmony
本文章所属专栏:Flutter for OpenHarmony
Flutter 状态管理入门实战
- 使用 Provider 构建计数器应用
- 一、为什么选择 Provider?
- 二、项目结构概览
- 三、定义状态模型:`CounterModel`
- ✅ 关键点解析:
- 四、应用入口:注入状态
- ✅ 关键点解析:
- 五、 主界面:`MyApp`
- 六、 计数器页面:`CounterScreen`
- ✅ 关键点解析:
- (1)读取状态:`Provider.of`
- (2)响应式显示:`Consumer`
- (3)事件绑定
- 七、运行效果与总结
- ✅ 优点总结:
- 完整代码

使用 Provider 构建计数器应用
在 Flutter 开发中,状态管理(State Management) 是构建可维护、可扩展应用的核心技能之一。本文将通过一个简洁但完整的“计数器”示例,深入讲解如何使用官方推荐的状态管理方案 —— Provider,实现数据驱动 UI 更新。
一、为什么选择 Provider?
Provider 是 Flutter 团队推荐的轻量级状态管理工具,具有以下优势:
- 基于
InheritedWidget封装,性能优秀 - 语法简洁,学习曲线平缓
- 支持响应式更新(自动 rebuild 相关 Widget)
- 与 Flutter 框架深度集成,社区支持广泛
二、项目结构概览
整个应用包含四个核心部分:
- 状态模型(CounterModel):管理计数逻辑
- 应用入口(main 函数):注入状态到 Widget 树
- 主界面(MyApp):配置 MaterialApp
- 计数器页面(CounterScreen):展示状态并提供交互
下面我们逐段解析。
三、定义状态模型:CounterModel
class CounterModel with ChangeNotifier {
int _count = 0;
int get count => _count;
void increment() {
_count++;
notifyListeners();
}
void reset() {
_count = 0;
notifyListeners();
}
}
✅ 关键点解析:
with ChangeNotifier
使该类具备通知能力。当调用notifyListeners()时,所有监听此对象的 Widget 会自动重建。私有变量
_count+ 公共 getter
封装数据,防止外部直接修改,确保状态只能通过方法变更(符合状态管理最佳实践)。notifyListeners()
触发 UI 更新的关键。每次状态改变后必须调用,否则界面不会刷新。
⚠️ 注意:不要在
build方法中直接调用notifyListeners(),否则会导致无限循环!
四、应用入口:注入状态
void main() {
runApp(
ChangeNotifierProvider(
create: (context) => CounterModel(),
child: const MyApp(),
),
);
}
✅ 关键点解析:
ChangeNotifierProvider
是 Provider 提供的专门用于包裹ChangeNotifier子类的 Provider。create回调
在此处创建CounterModel实例,并将其“注入”到 Widget 树中。整个 App 的子组件都可以通过Provider.of或Consumer访问它。作用域
由于放在MyApp外层,CounterModel对整个应用可见。
五、 主界面:MyApp
class MyApp extends StatelessWidget {
const MyApp({super.key});
Widget build(BuildContext context) {
return MaterialApp(
title: 'Provider 状态管理测试',
theme: ThemeData(primarySwatch: Colors.blue),
home: const CounterScreen(),
);
}
}
这是一个标准的 Flutter 应用壳,无特殊逻辑,仅用于启动 CounterScreen 页面。
六、 计数器页面:CounterScreen
class CounterScreen extends StatelessWidget {
const CounterScreen({super.key});
Widget build(BuildContext context) {
final counter = Provider.of<CounterModel>(context);return Scaffold(appBar: AppBar(title: const Text('VON - 状态管理测试')),body: Center(child: Column(mainAxisAlignment: MainAxisAlignment.center,children: [const Text('当前计数:', style: TextStyle(fontSize: 18)),Consumer<CounterModel>(builder: (context, model, child) {return Text('${model.count}', style: TextStyle(fontSize: 48));},),ElevatedButton(onPressed: counter.increment, child: Text('➕ 增加')),ElevatedButton(onPressed: counter.reset, child: Text('↺ 重置')),],),),);}}
✅ 关键点解析:
(1)读取状态:Provider.of
final counter = Provider.of<CounterModel>(context);
- 这行代码从上下文中获取
CounterModel实例。 - 默认情况下,
Provider.of会监听变化(即当notifyListeners()被调用时,当前 Widget 会 rebuild)。
如果你只想读取一次而不监听,可传入
listen: false:Provider.of<CounterModel>(context, listen: false)
(2)响应式显示:Consumer
Consumer<CounterModel>(builder: (context, model, child) {return Text('${model.count}');},)
Consumer是一种更精细的监听方式,只重建其内部的 builder 部分,而非整个CounterScreen。- 推荐用于局部状态更新,提升性能。
在本例中,其实两种方式效果相同。但若页面复杂,
Consumer更高效。
(3)事件绑定
onPressed: counter.increment
- 直接调用状态模型中的方法,触发状态变更 → 自动通知 UI 更新。
七、运行效果与总结
当你运行此应用:
- 初始显示
0 - 点击“增加” → 数字递增
- 点击“重置” → 回到
0 - 所有更新均由
Provider驱动,无需手动调用setState



✅ 优点总结:
- 逻辑与 UI 分离(关注点分离)
- 状态集中管理,易于调试和测试
- 代码简洁,可读性强
- 符合 Flutter 响应式编程思想
结语:状态管理不是炫技,而是为了写出更清晰、更可维护的代码。从
Provider入手,是你迈向 Flutter 高阶开发的重要一步。
完整代码
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
// 1. 状态模型:继承 ChangeNotifier
class CounterModel with ChangeNotifier {
int _count = 0;
int get count => _count;
void increment() {
_count++;
notifyListeners(); // 通知所有监听者重建
}
void reset() {
_count = 0;
notifyListeners();
}
}
// 2. 主应用入口
void main() {
runApp(
// 将 CounterModel 提供给整个 App
ChangeNotifierProvider(
create: (context) => CounterModel(),
child: const MyApp(),
),
);
}
// 3. 主界面
class MyApp extends StatelessWidget {
const MyApp({super.key});
Widget build(BuildContext context) {
return MaterialApp(
title: 'Provider 状态管理测试',
theme: ThemeData(primarySwatch: Colors.blue),
home: const CounterScreen(),
);
}
}
// 4. 计数器页面
class CounterScreen extends StatelessWidget {
const CounterScreen({super.key});
Widget build(BuildContext context) {
// 通过 Provider 读取状态
final counter = Provider.of<CounterModel>(context);return Scaffold(appBar: AppBar(title: const Text('VON - 状态管理测试')),body: Center(child: Column(mainAxisAlignment: MainAxisAlignment.center,children: [const Text('当前计数:',style: TextStyle(fontSize: 18),),// 使用 Consumer 自动监听变化(也可用 Selector 优化)Consumer<CounterModel>(builder: (context, model, child) {return Text('${model.count}',style: const TextStyle(fontSize: 48, fontWeight: FontWeight.bold),);},),const SizedBox(height: 30),Row(mainAxisAlignment: MainAxisAlignment.center,children: [ElevatedButton(onPressed: counter.increment,child: const Text('➕ 增加'),),const SizedBox(width: 20),ElevatedButton(onPressed: counter.reset,child: const Text('↺ 重置'),),],),],),),);}}