Flutter圈子Flutter学习日记Flutter

Flutter状态管理之provide和provider的使用区

2019-07-17  本文已影响10人  专心致志的程序员
E7BB7894-13E0-4857-B9AF-9037F4EE75A6.png
如图所示,我们要做的就是这个效果。首先我说一下这个页面的我理解的试图拆分。我首先把这个效果图拆分成三部分,左侧可滚动的ListView,右侧上不的ListView,以及商品详情的ListView,没错就是分成了三个ListView。并且左侧的ListView点击右侧的头部ListView以及商品详情都会跟着随之变动。
【好像扯远了!!!!!!!!!!!下面开始正题🔽】
首先我们要做的话肯定需要状态管理。我觉得状态管理就有点像iOS里面的通知。不知道理解的对不对,反正我觉得类似吧。
说道状态管理不得不说谷歌的亲自开发的两款状态管理Widget;第一个是provide,第二个是provider。这两个的区别就是一个出来的早,现在好像没整么更新了。第二个是今年(2019)最近才出来的目前的版本是provider: ^3.0.0+1。上一个停留在了provide: ^1.0.2,基本上GG了。但是有时候项目中可能用到了provide。所以现在我想说的是这两个的基本用法,或者说是两者使用的对比吧(控制多个界面的状态,项目中可能多个界面的状态管理更多)。

0️⃣

创建一个provide吧,其实可以说是一个model

import 'package:flutter/material.dart';

//混入
class Counter with ChangeNotifier{
  int value = 0;
increment(){
  value += 1;
    //发送通知
    NotificationListener();
  }
}

没错就这样搞一个简单的。

一、

顶层依赖管理
provide

void main() {
  //顶层依赖
var counter = Counter();
var providers = Provider();
  providers
    ..(Provider<Counter>.value(counter))
  runApp(ProviderNode(child: MyApp(), providers: providers));
}

没错就是这样。如果使用provider的话就不用这样写了。我们需要做的是这样
provider

class MyApp extends StatelessWidget {
var counter = Counter();
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
//这里是关键注册通知吧
        ChangeNotifierProvider(builder: (_) => counter),
      ],
      child: Container(
        child: MaterialApp(
          title: 'Test',
          onGenerateRoute: Application.router.generator,
          //去掉DEBUG字样
          debugShowCheckedModeBanner: false,
          //设置主题
          theme: ThemeData(primaryColor: Colors.pink),
          home: IndexPage(),
        ),
      ),
    );
  }
}

上面两个就是这两种的顶层依赖。

使用:

provide在具体方法中的使用

Provide.value<Counter>(context) .increment(掉一下里面的方法。。这里也可以传参数进去只需要在 Counter 里面的 increment 里面写两个接受参数的就好);

provider就这么写

Provider.of<Counter>(context, listen: false).increment(这里也可以传参数);

这样我们基本完成了把参数保存起来的效果。
再来个实际的例子

#注释掉的是我们”provide“ 的写法,这里主要是从我们建立的model里面取Id,因为Id是变化的。
var formData = {
      "categoryId": Provider.of<ChildCategory>(context)
          .categoryId, //Provide.value<ChildCategory>(context).categoryId,
      "categorySubId": categorySubId,
      "page": 1
    };

这样获取到值,但是有时候我们需要的是一个data之类的,比较多的值。那我们可以这样做
provide中:

return Provide<CategoryGoodsListProvide>(builder: (context, child, data) {
data.//也能点出我们设置好值
}

provider中:

final counter = Provider.of<Counter>(context);
    return Container(
      counter.//点出我们在model里面设置的值了
 );

重要提示:在使用 provider的时候我们要注意了一定要设置listen的Bool值就是这样

await Provider.of<DetailsInfoProvide>(context, listen: false).getGoodsInfo(goodsId);

附上项目github地址BXSH喜欢的朋友给个star吧!

上一篇下一篇

猜你喜欢

热点阅读