美文网首页
Provider-单页面的数据管理

Provider-单页面的数据管理

作者: edison0428 | 来源:发表于2020-03-09 16:40 被阅读0次

    前言

    flutter的状态管理有多种类,复杂程度,学习难度都不一样,最基本的要属于Stateful及其setState方法,但是数据变化时刷新绘制页面,资源有点浪费,其实我们只想要重绘某个变化的Widget即可,如Text()的文本变化,只要重绘Text就行,没有必要全部重绘,对于大型app显得更为重要.因此出现了多种状态管理的所谓框架
    这里介绍Provider的基本使用,可以用在程序入口级别的,就是把Provider包裹在MaterialApp的上面,如管理app的主题色或语言等,可以控制MaterialApp的数据变化,而普通的数据没有必要放在程序入口开始监控,这样会浪费资源,普通的状态管理只要在页面级别就可以.也就是把Provider包裹在Scaffold上面即可实施状态管理.

    准备工作

    依赖库 provider: ^4.0.2
    导入类 import ‘package:provider/provider.dart’;

    相关类的构造函数

    1 类MultiProvider构造函数题
    MultiProvider({
        Key key, 
        List<SingleChildWidget> providers, 
        Widget child})
    
    2 类ChangeNotifierProvide构造函数题
    ChangeNotifierProvider<Counter> ChangeNotifierProvider(              //Counter是举例的类,T代替
            {Key key}, 
            {Counter Function(BuildContext) create}, 
            {bool lazy}, 
            {Widget child})
    

    举例ChangeNotifierProvider(create: (_) => Counter()),

    3 类Consumer构造函数题
    Consumer<Counter> Consumer(                //Counter是例子中的类
        {Key key}, 
        {Widget Function(BuildContext, Counter, Widget) builder}, 
        {Widget child})
    
    

    四 步骤

    1.模型定义
    class Counter with ChangeNotifier {           //with类型的类ChangNotifier
      int _count = 0;
      int get count => _count;
      void increment() {
        _count++;
        notifyListeners();  }}                     //通知监听
    
    

    代码

    class FristPage extends StatefulWidget {
      @override
      _FristPageState createState() => _FristPageState();
    }
    
    class _FristPageState extends State<FristPage> {
      @override
      Widget build(BuildContext context) {
        print('页面重绘了。。。。。。。。。。。');
        return ChangeNotifierProvider(
          create: (_) => Counter(),
          child: Scaffold(
            appBar: PreferredSize(
              preferredSize: Size.fromHeight(30),
              child: AppBar(
                title: Builder(builder: (BuildContext context){
                  print("导航栏 页面级别的 Provider.of 刷新");
                  return Text("导航栏 页面级别的 Provider.of${Provider.of<Counter>(context).value}");
                }),
              ),
            ),
            body: Container(
              width: double.infinity,
              margin: EdgeInsets.all(10),
              child: Column(
                //mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: <Widget>[
                  Consumer(builder:
                      (BuildContext context, Counter icounter, Widget child) {
                        print("body 页面级别的 consumer 刷新");
                    return Text(
                      "Consumer包裹的文本+${icounter.value}", //没有用consumer包裹的不会自动更新,只有页面重绘时才被更新
                      style: TextStyle(fontSize: 20),
                    );
                  }),
    
                  SizedBox(
                    height: 10,
                  ),
                  Container(
                    child: Builder(builder: (BuildContext context){
                      print("body 页面级别的 Provider.of 刷新");
                      return Text("body 页面级别的 Provider.of:${Provider.of<Counter>(context).value}");
                    }),
                  ),
                  SizedBox(
                    height: 10,
                  ),
                  Consumer(
                    builder:
                        (BuildContext context, Counter counter, Widget child) {
                      return RaisedButton(
                        child: Icon(Icons.add),
                        onPressed: counter.addValue,
                      );
                    },
                  ),
                  SizedBox(
                    height: 10,
                  ),
                  DataWidget(), //抽离后的数据展示
                ],
              ),
            ),
              floatingActionButton: FloatingActionButton(
                onPressed: (){
                  Navigator.of(context).push(MaterialPageRoute(builder: (context) => SecondPage()));
                },
                tooltip: 'Increment',
                child: Icon(Icons.add),
              )
    
          ),
        );
      }
    }
    

    注意点,如果是在包含Scaffold的类里不能用Provider.of
    解决方法1 用Build方法来包裹Scaffold

    child: Builder(
            builder: (BuildContext context){
              return Scaffold(...)
    

    解决方法2或者包裹需要展示数据的那个Widget

    Builder( builder: (BuildContext context){
                      return Text("用Build返回后利用Provider.of获取值:${Provider.of<Counter>(context).value}");})
    

    相关文章

      网友评论

          本文标题:Provider-单页面的数据管理

          本文链接:https://www.haomeiwen.com/subject/htbpdhtx.html