Flutter Provider状态管理的八种提供者、四种消费者(下)

Flutter Provider状态管理的八种提供者、四种消费者(下)



前言

作者的整理了Provider状态管理的八种提供者和四种消费者的介绍和使用。这篇文章可以告诉你Provider到底是个什么,如何使用。作者能力有限该文章不涉及源码的讲解!建议先去了解一下Buildcontext context(Element)的作用便于理解。


Provider的八种提供者

Flutter Provider状态管理的八种提供者、四种消费者(上)

Provider的四种消费者

一、Provider.of

static T of<T>(BuildContext context, {bool listen = true}) {
assert(
context.owner!.debugBuilding ||
listen == false ||
debugIsInInheritedProviderUpdate,
,
);

final inheritedElement = _inheritedElementOf<T>(context);

if (listen) {
context.dependOnInheritedWidgetOfExactType<_InheritedProviderScope<T?>>();
}

final value = inheritedElement?.value;

if (_isSoundMode) {
if (value is! T) {
throw ProviderNullException(T, context.widget.runtimeType);
}
return value;
}

return value as T;
}

static _InheritedProviderScopeElement<T?>? _inheritedElementOf<T>(
BuildContext context,
) {
assert(context != null, '''
''');
assert(
_debugIsSelecting == false,
);
assert(
T != dynamic,

);
final inheritedElement = context.getElementForInheritedWidgetOfExactType<
_InheritedProviderScope<T?>>() as _InheritedProviderScopeElement<T?>?;

if (inheritedElement == null && null is! T) {
throw ProviderNotFoundException(T, context.widget.runtimeType);
}

return inheritedElement;
}



具体使用
Text(Provider.of<CountNotifier1>(context).count.toString(),
              style: TextStyle(
                color: Colors.red,
                fontSize: 50,
              ),
            ),


Provider,of 通过BuildContext context, {bool listen = true} 默认参数 去监听参数,使用context调用上级CountNotifier(T类型模型)的数据。如果不知道为什么的,需要了解一下BuildContext context。

如果需要从Widget树外部监听提供者公开的值,需要设置为listen = false。

二.Cousumer

Consumer只是在widget中调用了Provider.of ,并将其构造实现委托给了构造器,比如我们常见的Builder,如果你的Widget依赖多个模型,那么它还提供了Cousumer23456方便使用。
在这里插入图片描述
Consumer有三个参数,Key,Builder ,和一个 child(子widget)
在这里插入图片描述

代码如下(示例):

Consumer<UserModel1>(
              builder : (_,userModel,child){   // _ 为Buildercontext context
                return Text(userModel.name,
                  style: TextStyle(
                    color:  Colors.red,
                    fontSize: 30,
                  ),
                );
              },
            ),
);
2代表模型的个数 还有3456可以使用
Consumer2<UserModel1,UserModel4>(
              builder: (_,userModel1,userModel4,child){
                return Padding(
                  padding: EdgeInsets.all(20),
                  child: ElevatedButton(
                    onPressed: (){
                       userModel4.changeName();
                      userModel1.changeName();
                    },
                    child: Text("改变值"),
                  ),
                );
              },
     




该处使用的url网络请求的数据。

当然如果要child需要单独的声明来保证该参数不为空

三.Selector

Selector和Consumer类似,只是对Build调用widget方法时提供更精细的控制,简单点来说,Selector也是一个消费者,它允许你可以从模型中准备定义那些属性。
在这里插入图片描述
两个必选参数
ValueWidgetBuilder
在这里插入图片描述

代码如下(示例):

child: Selector<UserModel6, int>(
          selector: (_,userModel6) => userModel6.age, // int age
          builder: (_,age,child){
            return Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Text(age.toString(),
                style: TextStyle(
                  color: Colors.red, fontSize: 38,
                ),
                ),
               child
              ],
            );
          },
          child: Padding(
            padding: EdgeInsets.all(20),
            child: ElevatedButton(
              onPressed: (){
                Provider.of<UserModel6>(context,listen: false).increaseAge();
              },
              child: Text("改变年龄"),
            ),
          ),

Selector依旧支持多个选择 有Selector23456

四.InherContext

InheritedContext是provider内置扩展了BuildContext,它保存了组件在树中自己位置的引用,我们在上面的案例中见到Provider.of(context,listen : false),其实这个of方法就是使用Flutter查找树并找到Provider子类型为CountNotifier而已

三大方式

BuildContext.read:

BuildContext.read可以替换掉Provider.of(context,listen : false) ,它会找到CountNotifier返回
在这里插入图片描述
所以可见 read()就是调用了Provider.of(this,listen: false);

BuildContext.watch:

BuildContext.watch可以替换掉Provider.of(context,listen : false) ,看起来和read没有什么不同,但是使用watch你就不需要使用Consumer。
在这里插入图片描述
listen: 默认为true;

BuildContext.select:

BuildContext.read可以替换掉Provider.of(context,listen : false) ,看起来和Watch也没有什么不同,但是使用select你就不需要再使用Selector

R select<T, R>(R Function(T value) selector) 

ListView.builder(
      itemBuilder: (context, index) {
        return Builder(builder: (context) {
          final todo = context.select((TodoList list) => list[index]);
          return Text(todo.name);
        });
      },
    );

总结

祝大家乘风破浪

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值