背景

provide是谷歌官方出品的一个状态管理框架flutter-provide,它允许在小部件树中传递数据,它被设计为ScopedModel的替代品,允许我们更加灵活地处理数据类型和数据

为什么需要状态管理

在进行项目的开发时,我们往往需要管理不同页面之间的数据共享,在页面功能复杂,状态达到几十个上百个的时候,我们会难以清楚的维护我们的数据状态,本文将以主题切换这个功能使用状态管理来讲解如何在Flutter中使用provide这个状态管理框架

为什么选择Provide

一开始项目使用的是ScopedModel,使用ScopedModel可以分离展示逻辑和业务逻辑,而且简单易用,但是ScopedModel有一些局限

如果模型较为复杂,当状态更新时,会有较多的不必要的更新

使用Provide

当状态发生变化时,widget树会更新指定的节点,不会进行整颗widget树的更新

Provide有泛型的优势,相当于namespace的特性,使用过vuex的应该知道namespace的重要性,它将我们的状态分离开来

Provide被设计为ScopedModel的替代品,同样也有和ScopedModel的易用性

Provide提供了Provide.stream可以以处理流的方式处理数据,不过目前还存在一些问题

项目地址

flutter-ui, 可参考项目中使用provide方法

效果

af78eabb943b2fe8b6a99f23a0c834eb.png

如何使用

添加依赖

在pubspec.yaml中引入依赖

dependencies:

provide: ^1.0.2 #数据管理层

执行

flutter packages get

在需要使用的页面中引入

import 'package:provide/provide.dart'

创建model (这才第一步)

新建 lib/store/models/config_state_model.dart 文件

import 'package:flutter/material.dart';

import 'package:flutter/foundation.dart' show ChangeNotifier

class ConfigInfo {

String theme = 'red';

}

class ConfigModel extends ConfigInfo with ChangeNotifier {

Future $setTheme(payload) async {

theme = payload;

notifyListeners();

}

}

用法同ScopedModel差不多,不过不需要继承Model类,只需要混入ChangeNotifier,通过notifyListeners通知听众刷新

封装Store (没错,到这里已经要快完成所有步骤了)

新建 lib/store/index.dart 文件

import 'package:flutter/material.dart'

import 'package:provide/provide.dart'

show

Providers

Provider,

Provide,

ProviderNode;

import './models/config_state_model.dart' show ConfigModel;

class Store {

// 我们将会在main.dart中runAPP实例化init

static init({model, child, dispose = true}) {

final providers = Providers()

..provide(Provider.value(ConfigModel()));

return ProviderNode(

child: child,

providers: providers,

dispose: dispose

);

}

// 通过Provide小部件获取状态封装

static connect({builder, child, scope}) {

return Provide(

builder: builder,

child: child,

scope: scope

);

}

// 通过Provide.value(context)获取封装

static T value(context, {scope}) {

return Provide.value(context, scoped: scoped);

}

}

需要管理多个状态只需要

final providers = Providers()

..provide(Provider.value(ConfigModel()))

..provide(Provider.value(More()));

定义全局的Provide (倒数第二)

lib/main.dart 文件

import 'package:flutter/material.dart';

import 'package:efox_flutter/store/index.dart'

show Store, ConfigModel;

// 将状态放入到顶层

void main() => runApp(Store.init(child: MainApp()));

class MainApp extends StatefulWidget {

@override

MainAppState createState() => MainAppState();

}

class MainAppState extends State {

@override

Widget build(BuildContext context) {

// 获取Provide状态

return Store.connect(

builder: (context, child, model) {

return MaterialApp(

theme: ThemeData(

primaryColor: Color(model.theme)

)

);

}

);

}

}

改变主题状态 (完成)

import 'package:flutter/material.dart';

import 'package:efox_flutter/store/index.dart'

show ConfigModel, Store;

/**

* name: 颜色名称 如 red

* color:颜色值

* context: 上下文

*/

Widget Edage(name, color, context) {

return GestrueDetector(

onTap: () {

// 修改主题状态

Store.value(context).$setTheme(name)

}

child: Container(

color: Color(color),

height: 30,

widtg: 30

)

);

}

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对脚本之家的支持。

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐