Flutter状态管理Provider,简单上手

学习Flutter一段时间了,偶然看到大家都说状态管理,多数人都是用redux,对于一个Android开发人员来说之前根本没接触过,于是开始了解redux,之后又了解闲鱼推出的fish_redux,然后又看到Vadaski发表的一系列关于Flutter状态管理的文章,包括Scoped Model, Redux, BLoC,RxDart,provide(想了解的可以移步),看的是眼花缭乱。对于Redux,能看懂是怎么写的,但真要到应用的层面,感觉还是有些吃力,更不知道怎样维护好它,一时间也不知道用什么什么适合自己。后来又接触到google推荐的Provider,于是学习了下。接下来就用Provider来实现一个计数的例子。

第一步,添加Provider依赖

provider: ^2.0.1+1
复制代码

pub地址:pub.dev/packages/pr…

第二步,创建Model

import 'package:provider/provider.dart';
class Counter with ChangeNotifier {//1
  int _count;
  Counter(this._count);

  void add() {
    _count++;
    notifyListeners();//2
  }
  get count => _count;//3
}
复制代码

简单的一个Counter对象,里面只有一个字段_count

  1. 这里需要混入ChangeNotifier
  2. 写一个增加的方法,然后需要调用notifyListeners();这个方法是通知用到Counter对象的widget刷新用的。
  3. get方法

第三步,使用ChangeNotifierProvider

通常main()方法是这么写

main() {
  runApp(MyApp());
}
复制代码

我们要监听改变就要在MyApp()外面套一层,这个是全局的,于是如下

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

main() {
  runApp(ChangeNotifierProvider<Counter>.value(//1
    notifier: Counter(1),//2
    child: MyApp(),
  ));
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
      title: "Provider",
      home: HomePage(),
    );
  }
}

复制代码
  1. ChangeNotifierProvider调用value()方法,里面传出notifierchild
  2. notifier设置了默认的Counter(1)

当然Provider不止提供了ChangeNotifierProvider,还有Provider,ListenableProvider,ValueListenableProvider,StreamProvider, 具体可以看wiki. 如果想管理多个对象可以用MultiProvider,如下

MultiProvider(
  providers: [
    Provider<User>.value(value: user),
    Provider<Goods>.value(value: goods),
    .....
  ],
  child: someWidget,
)
复制代码

第四步,使用Provider获取Counter的值

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

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text("Home"),
        actions: <Widget>[
          FlatButton(
            child: Text("下一页"),
            onPressed: () =>
                Navigator.push(context, MaterialPageRoute(builder: (context) {
                  return SecondPage();
                })),
          ),
        ],
      ),
      body: Center(
        child: Text("${Provider.of<Counter>(context).count}"),//1
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          Provider.of<Counter>(context).add();//2
        },
        child: Icon(Icons.add),
      ),
    );
  }
}
复制代码
  1. Provider.of<Counter>(context).count获取_count的值,Provider.of<T>(context)相当于Provider去查找它管理的Counter(1)
  2. Provider.of<Counter>(context).add();调用Counter()中的add()方法

同样第二个页面也这样写,如下

class SecondPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text("SecondPage"),
      ),
      body: Center(
        child: Text("${Provider.of<Counter>(context).count}"),//1
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          Provider.of<Counter>(context).add();//2
        },
        child: Icon(Icons.add),
      ),
    );
  }
}
复制代码

这样,当每个页面都点击+号按钮时,_count便会+1,同时通知并更新到使用它的地方。

完整代码,copy后可直接运行

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

main() {
  runApp(ChangeNotifierProvider<Counter>.value(
    notifier: Counter(1),
    child: MyApp(),
  ));
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
      title: "Provider",
      home: HomePage(),
    );
  }
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text("Home"),
        actions: <Widget>[
          FlatButton(
            child: Text("下一页"),
            onPressed: () =>
                Navigator.push(context, MaterialPageRoute(builder: (context) {
                  return SecondPage();
                })),
          ),
        ],
      ),
      body: Center(
        child: Text("${Provider.of<Counter>(context).count}"),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          Provider.of<Counter>(context).add();
        },
        child: Icon(Icons.add),
      ),
    );
  }
}

class SecondPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text(Provider.of<String>(context)),
      ),
      body: Center(
        child: Text("${Provider.of<Counter>(context).count}"),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          Provider.of<Counter>(context).add();
        },
        child: Icon(Icons.add),
      ),
    );
  }
}

class Counter with ChangeNotifier {

  int _count;

  Counter(this._count);

  void add() {
    _count++;
    notifyListeners();
  }

  get count => _count;
}
复制代码

总结

看了那么多状态管理的,个人感觉Provider还是属于简单易用的,并且是google推荐的。但感觉还需要成长,让大家认可。我这里只是一个简单的使用,有一些地方也没讲太清楚还请大家见谅,同时也希望和各位学习Flutter的同学互相交流进步。

转载于:https://juejin.im/post/5d01f7826fb9a07ee742d9c4

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值