Javascript is required
Flutter-Provider

前言

一个应用内通常会有两种数据,部件内部的使用的临时性数据以及很多部件使用的全局性数据,部件内部使用的数据可以通过 StatefulWidget 来管理,但是全局性的数据如果通过从上到下传递的方式会使代码写的十分繁琐,这时就需要一个状态管理工具来进行管理了

应用中通常会有一些很多部件都需要的数据,如用户的登录信息,用户设置,地理位置等,如果只是使用 StatefullWeight 的话就需要将状态提升到一个父部件中然后向下进行传递,会很繁琐,使用 provider 的话可以将对一种状态数据的操作放到一个文件内,然后使用到这个数据的部件只需要使用就可以了,当数据有变化时,部件会自动的重新构建,使界面更新。

Provider

官方的定义是: A mixture between dependency injection (DI) and state management, built with widgets for widgets. 翻译过来大意是一种依赖注入和状态管理的混合方案,使用部件创建,作用于部件

https://pub.flutter-io.cn/documentation/provider/latest/

使用状态管理

image-20201126130703054

StatefulWidget

StatefulWidget + setState

在不使用任何第三方包的时候,官方也提供了不错的选择,那就是StatefulWidget,当我们需要改变状态来刷新UI时,只需要调用setState()方法。

image-20201126094615028

Provider

这是一种先进的状态管理和依赖注入的工具,并且易于学习和理解,所以目前官方也推荐首选Provider

加入依赖

dependencies:
  provider: ^4.3.2+2

步骤

  1. 继承ChangeNotifier => store文件

创建状态模型对象。

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';


class CounterProvider with ChangeNotifier, DiagnosticableTreeMixin {
  bool flag = true;
  int _counter;

  CounterProvider(this._counter);

  getCounter() => _counter;
  setCounter(int counter) => _counter = counter;

  void add(){
    _counter++;
    notifyListeners();
  }
  void sub(){
    _counter--;
    notifyListeners();
  }
}

它所做的就是在案例计数器类中为我们的类添加侦听功能。

在add和sub方法都有一个方法notifyListeners

  1. 包装

它是状态管理的助手。它是一个小部件,可为其下方的小部件提供一些值(如状态模型对象)。

提供者的小部件树

image-20201126125535615

import 'package:provider/provider.dart';
import 'package:demo/store/index.dart';

void main() {
  runApp(
    MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_)=> CounterProvider(1)), // 调用C ounterProvider()
      ],
      child: MyApp(),
    )
  );
}
  1. 引用
import 'package:provider/provider.dart';
import 'package:demo/store/index.dart';  // 引入自己的Provider包

image-20201126110153283

import 'package:provider/provider.dart';
import 'package:demo/store/index.dart'; // CounterProvider

// 引用方法
onPressed: (){
  context.read<CounterProvider>().add(); // 调用add方法
},

// 引用变量
Text('${context.watch<CounterProvider>().getCounter()}')
  1. 验证

多个Widget使用相同的状态

一旦状态改变,所有与其相关的Widget接受通知

再次创建一个Widget

image-20201126130215640

参考

https://pub.dev/packages/provider/example

https://segmentfault.com/a/1190000022263763

https://www.raywenderlich.com/6373413-state-management-with-provider