Flutter练习(九)—状态管理工具一(Provider)

256 阅读2分钟

前言

Provider 是 Google 官方推荐的Flutter页面状态管理工具,是对InheritedWidget 组件的上传封装,使其更易使用,更易复用,Provider 相对InheritedWidget ,有以下优势:

  • 简化的资源分配与处置
  • 懒加载
  • 创建新类时减少大量的模板代码
  • 支持 DevTools
  • 更通用的调用 InheritedWidget 的方式
  • 提升类的可扩展性,整体的监听架构时间复杂度以指数级增长

接下来我们介绍 Provider 的两个元素,并通过其实现APP置灰的DEMO

数据提供者

  • Provider (数据变化,不更新 UI)
  • ChangeNotifierProvider (数据变化,自动更新 UI)
  • MultiProvider (使用多个数据源)
  • InheritedProvider
  • FutureProvider
  • StreamProvider
  • ChangeNotifierProxyProvider (23456)
  • ProxyProvider (23456)

数据使用者

  • Provider.of()
  • Consumer(23456)(部分刷新)
  • Selector(23456)(部分刷新,比 Consumer 更为精细控制)
  • InheritedContext

安装依赖

yaml 文件中添加依赖

dependencies:
  provider: ^6.0.2

创建相应数据类型

import 'package:flutter/material.dart';

/// 系统相应状态
class AppState with ChangeNotifier {
  late bool _isGrayFilter;

  get isGrayFilter => _isGrayFilter;

  AppState({bool isGrayFilter = false}) {
    _isGrayFilter = isGrayFilter;
  }

  // 切换灰色滤镜
  switchGrayFilter() {
    _isGrayFilter = !_isGrayFilter;
    notifyListeners();
  }
}

创建相应数据

方式一、先创建对象,再挂载

注册相应的全局APPState()

class Global {
  /// 应用状态
  static AppState appState = AppState();
  
}
void main() => Global.init().then((e) => runApp(
      MultiProvider(
        providers: [
          ChangeNotifierProvider<AppState>.value(
            value: Global.appState,
          ),
        ],
        child: MyApp(),
      ),
    ));

方式二、先挂载,再创建对象

void main() => Global.init().then((e) => runApp(
      MultiProvider(
        providers: [
          ChangeNotifierProvider<AppState>(
            Create: (_) => new AppState(),
          ),
        ],
        child: MyApp(),
      ),
    ));

创建数据使用者,通知数据变化

void main() => Global.init().then((e) => runApp(MultiProvider(
      // provider 的使用
      providers: [
        ChangeNotifierProvider<AppState>.value(
          value: Global.appState,
        ),
      ],
      child: Consumer<AppState>(
        builder: (context, appState, _) {
          if (appState.isGrayFilter) {
            return ColorFiltered(
              colorFilter:
                  const ColorFilter.mode(Colors.white, BlendMode.color),
              child: MyApp(),
            );
          } else {
            return MyApp();
          }
        },
      ),
    )));

页面中调用方法,实现APP整体置灰

import 'package:flutter/material.dart';
import 'package:flutter_news_demo/provider/provider.dart';
import 'package:provider/provider.dart';

class AccountPage extends StatefulWidget with AutoRouteAware{
  AccountPage({Key? key}) : super(key: key);

  @override
  _AccountPageState createState() => _AccountPageState();
}

class _AccountPageState extends State<AccountPage> {

  @override
  void initState() {
    super.initState();
  }

  @override
  void dispose() {
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final appState = Provider.of<AppState>(context);

    return Container(
      child: Column(
        children: [
          MaterialButton(
            onPressed: () {
              appState.switchGrayFilter();
            },
            child: Text('灰色切换 ${appState.isGrayFilter}'),
          ),
        ],
      ),
    );
  }
}

页面效果如下