Flutter体验 Day 20-Provider

Provider

Provider封装了 InheritedWidget 功能,提供更高效且易懂的使用方式。

引言 Provider说明文件

By using provider instead of manually writing InheritedWidget, you get:

  • simplified allocation/disposal of resources
  • lazy-loading
  • a vastly reduced boilerplate over making a new class every time
  • friendly to devtools
  • a common way to consume these InheritedWidgets (See Provider.of/Consumer/> Selector)
  • increased scalability for classes with a listening mechanism that grows > exponentially in complexity (such as ChangeNotifier, which is O(N) for > dispatching notifications).

全局性的状态管理

StatefullWidget中我们可以透过State处理一个Widget的状态管理,但是实务上在应用程序的开发过程里往往会需要一个全局性的状态管理的解决方案,在官网这边有提供其他选项让开发人员自己选择理想的套件,而 Provider 是 Google 官方建议使用的第三方套件。

重要元件

  • ProviderProvider套件根据资料来源的不同提供多种 Provder 组件处理不同资料的供应来源
  • Consumer:使用Consumer组件的builder 的方式取得资料
  • Selector:类似Consumer,对於复杂资料源提供更进阶的取用方式
  • of:组件内部使用BuildContextof方法取得资料
  • ChangeNotifier:Flutter SDK 内部的 mixin 类别,用来实现「观察者模式」的方法

范例

先前在介绍 Widget状态管理章节时我们有完成一个显示时间更新的范例,今天我们就使用 Provider 来改写看看吧。

  • Providers

内部提供多个组件处理不同的资料来源

  1. ChangeNotifierProvider
  2. ValueNotifier
  3. MultiProvider
  4. ProxyProvider
  5. FutureProvider
  6. StreamProvider

原本范例中自定义的TimeModel类别实现ChangeNotifier功能,我们可以在使用ChangeNotifierProvider定义资料来源


class ProviderScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("Provider")),
      body: ChangeNotifierProvider(
        create: (context) => TimeModel(),
        child: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            children: [
              TimeConsumerWidget(),
              TimeOfWidget(),
            ],
          ),
        ),
      ),
    );
  }
}
  • Consumer builder() 取用方式
class TimeConsumerWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Consumer<TimeModel>(
      builder: (context, time, child) {
        return Text("Consumer: ${time.toString()}");
      },
    );
  }
}
  • of() 取用方式
class TimeOfWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    var time = Provider.of<TimeModel>(context);
    return Text("of(): ${time.toString()}");
  }
}

widget_provider;

小结

练习成果


<<:  12 - fzf - 档案与目录模糊搜寻指令工具

>>:  Day 28 - AWS Lambda 结合 Dynamodb

[Day12] swift & kotlin 实作篇!(3) 专案架构介绍

swift 专案新增好了 接下来我们大致讲解一下 swift的专案架构与编辑器功能吧 项目名称 说明...

【Day11】Git 版本控制 - git clone & git pull

已经讲解完「如何将档案在本地数据库与 GitHub 进行版本控制」後,接下来,我们来讲讲 git c...

{CMoney战斗营} 的第十五周 # NoSql

目前最常被开发者使用的资料库系统为关联式资料 NoSQL: 全名为「Not only SQL」,也就...

Day 21 评估Privacy by Design实作

透过之前隐私规划经验实例跟各位分享,当规划一项产品时所需注意留意各方的隐私规划项目,在app端、cl...

SQL JOIN 共七种

没有搞懂它前,似懂非懂的,东拚西凑,也能写出程序. 但搞懂它,更知道自己在写什麽. key word...