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

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



✅ 优点总结:
- 逻辑与 UI 分离(关注点分离)
- 状态集中管理,易于调试和测试
- 代码简洁,可读性强
- 符合 Flutter 响应式编程思想
🌟 结语 :状态管理不是炫技,而是为了写出更清晰、更可维护 的代码。从
Provider入手,是你迈向 Flutter 高阶开发的重要一步。
完整代码
dart
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});
@override
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});
@override
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('↺ 重置'),
),
],
),
],
),
),
);
}
}