乐趣区

关于python:Flutter-Provider的使用

在应用 Provider 的时候,次要关怀三个概念:

  • ChangeNotifier:真正数据(状态)寄存的中央
  • ChangeNotifierProvider:Widget 树中提供数据(状态)的中央,会在其中创立对应的 ChangeNotifier
  • Consumer:Widget 树中须要应用数据(状态)的中央

代码:

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

void main() {runApp(MyApp());
}

//^ 1. ChangeNotifier:真正数据(状态)寄存的中央
//^ 2. ChangeNotifierProvider:Widget 树中提供数据(状态)的中央,会在其中创立对应的 ChangeNotifier
//^ 3. Consumer:Widget 树中须要应用数据(状态)的中央

// ! 1. 创立 ChangeNotifier, 实际上就是咱们的状态,它不仅存储了咱们的数据模型,还蕴含了更改数据的办法,并暴露出它想要暴露出的数据
class Counter with ChangeNotifier {
  int _count = 0;
  int get count => _count;

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

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {

    //! 2. ChangeNotifierProvider. 在 Widget Tree 中插入 ChangeNotifierProvider,以便 Consumer 能够获取到数据

    // 创立顶层共享数据。这里应用 MultiProvider 能够创立多个共享数据,因为理论的利用不可能只有一个数据模型

    return MultiProvider(
      providers: [ChangeNotifierProvider(create: (_) => Counter()),
      ],
      child: MaterialApp(
        title: 'Flutter Demo',
        home: FirstPage(),),
    );
  }
}

class FirstPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("第一个页面"),
        actions: <Widget>[
          FlatButton(child: Text("下一页"),
            onPressed: () =>
                Navigator.push(context, MaterialPageRoute(builder: (context) {return SecondPage();
            })),
          ),
        ],
      ),
      body: Center(child: Consumer<Counter>(builder: (ctx, counterPro, child) {
          return Text("以后计数:${counterPro.count}",
            style: TextStyle(fontSize: 20, color: Colors.red),
          );
        }),
      ),
      //! 3. Consumer:Widget 树中须要应用数据(状态)的中央
      floatingActionButton: Consumer<Counter>(builder: (ctx, counterPro, child) {
          //* ctx: context, 上下文, 目标是晓得以后树的对象
          //* counterPro: ChangeNotifier 对应的实例,也是咱们在 builder 函数中次要应用的对象
          //* child: 目标是进行优化,如果 builder 上面有一颗宏大的子树,当模型产生扭转的时候,咱们并不心愿从新 build 这颗子树,那么就能够将这颗子树放到 Consumer 的 child 中,在这里间接引入即可.
          return FloatingActionButton(
            child: child,
            onPressed: () {counterPro.increment();
            },
          );
        },
        child: Icon(Icons.add), //! Icon 放在 builder 里面, 避免每次跟着一起刷新
      ),
    );
  }
}

class SecondPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("第二个页面"),
        actions: <Widget>[
          FlatButton(child: Text("上一页"),
            onPressed: () =>
                Navigator.push(context, MaterialPageRoute(builder: (context) {return FirstPage();
            })),
          ),
        ],
      ),
      body: Center(child: Consumer<Counter>(builder: (ctx, counterPro, child) {
          return Text("以后计数:${counterPro.count}",
            style: TextStyle(fontSize: 20, color: Colors.red),
          );
        }),
      ),
      floatingActionButton: Consumer<Counter>(builder: (ctx, counterPro, child) {
          return FloatingActionButton(
            child: child,
            onPressed: () {counterPro.increment();
            },
          );
        },
        child: Icon(Icons.add),
      ),
    );
  }
}


  • 参考文章
  • 官网文档

  • 简繁火星字体转换
  • 哄女友神器
  • 号码测吉凶
  • 电视节目直播表
退出移动版