Flutter for OpenHarmony前置知识《Flutter 状态管理入门实战:使用 Provider 构建计数器应用》

Flutter 状态管理入门实战


🧠使用 Provider 构建计数器应用

在 Flutter 开发中,状态管理(State Management) 是构建可维护、可扩展应用的核心技能之一。本文将通过一个简洁但完整的"计数器"示例,深入讲解如何使用官方推荐的状态管理方案 ------ Provider,实现数据驱动 UI 更新。


一、为什么选择 Provider?

Provider 是 Flutter 团队推荐的轻量级状态管理工具,具有以下优势:

  • 基于 InheritedWidget 封装,性能优秀
  • 语法简洁,学习曲线平缓
  • 支持响应式更新(自动 rebuild 相关 Widget)
  • 与 Flutter 框架深度集成,社区支持广泛

二、项目结构概览

整个应用包含四个核心部分:

  1. 状态模型(CounterModel):管理计数逻辑
  2. 应用入口(main 函数):注入状态到 Widget 树
  3. 主界面(MyApp):配置 MaterialApp
  4. 计数器页面(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.ofConsumer 访问它。

  • 作用域

    由于放在 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('↺ 重置'),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}
相关推荐
艾小码1 小时前
Vue开发三年,我才发现依赖注入的TypeScript正确打开方式
前端·javascript·vue.js
Evan Wang2 小时前
深度解析GetX依赖注入,从Spring与Vue视角看Flutter架构
vue.js·spring boot·flutter
xiaocao_10232 小时前
在鸿蒙手机上有哪些比较高效的待办清单记事软件?
华为·智能手机·harmonyos
Karl_wei7 小时前
桌面应用开发,Flutter 与 Electron如何选
windows·flutter·electron
veneno9 小时前
大量异步并发请求控制并发解决方案
前端
i***t9199 小时前
Spring Boot项目接收前端参数的11种方式
前端·spring boot·后端
oden9 小时前
2025博客框架选择指南:Hugo、Astro、Hexo该选哪个?
前端·html
小光学长9 小时前
基于ssm的宠物交易系统的设计与实现850mb48h(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
java·前端·数据库