Flutter利用Provider程序入口级别的状态管理

前言

Flutter利用第三方的Provider来状态管理,对新手而言相对容易一点,这里介绍通过Provider来改变APP的主题色,示例程序做得非常简单,主要帮助区理解和熟悉Provider的使用.
在这里插入图片描述

准备

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

相关

步骤

用于管理主题颜色的状态等MaterialApp级别的应用场景

步骤1 定义管理

用with类型的ChangeNotifier 建立需监管的数据类

class Counter with ChangeNotifier {
  int _count = 1;                      和ScopedModel相似,分离数据继承ChangeNotifer
  Color _themeColor = Colors.redAccent;
  int get value => _count;
  Color get themeColor => _themeColor;
  void addValue() {    _count++;    notifyListeners();  }
  Color changeThemeColor({Color color: Colors.teal}) {
    _themeColor = color;    notifyListeners();
    return _themeColor;  }}    void可以不用返回
步骤2放置监控

用MultiProvider来包裹MaterialApp

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    Color _themeColor;
    return MultiProvider(                                     //放置监控
      providers: [ChangeNotifierProvider(create: (_) => Counter())],  //数据绑定
      child: Consumer(                                      //数据展示
          builder: (BuildContext context, Counter counter, Widget child) {
        _themeColor = counter.themeColor;
        return MaterialApp(
          debugShowCheckedModeBanner: false,
          theme: ThemeData(
            primaryColor: _themeColor,          ),
          home: MyHome(),        );      }),    );  }}
步骤3 数据绑定
providers: [ ChangeNotifierProvider<Counter>(create: (_) => Counter(), ) ],
步骤4 数据展示

展示的方式1

Counter counter = Provider.of<Counter>(context);      //提前获取Counter实例
Provider.of<Counter>(context).value     //引起整个页面的重绘,可以用上面counter.value
Provider.of<Counter>(context, listen: false).addValue();

Provider数据展示和InheritedWidget有点类似,
也可以用Consumer来展示数据和ScopedModel类似
除了像上一步中使用Consumer可以获取到当前的model数据之外,还可以使用Provider.of;
但是使用Provider.of,默认使用时,Model中的 notifyListeners() 被调用后,所有这个Model关联的Consumer的build方法都会被调用,也就是会刷新相关联的Widget;

步骤5 数据展示

展示方式2
可用Consumer来包裹某个Widget来

Consumer(       //可作为组件来用返回Widget  ,是build方法
              builder: (BuildContext context,Counter counter,Widget child){  //Counter为
                return Text("通过consumer获取的值:${counter.value}"); },)   //只重绘这个

和ScopedModelDescendant差不多

ScopedModelDescendant<CounterModel>(      //用这个区包裹需要变化管理的Widget
        builder: (context,_,model)=>ActionChip(
          label: Text("${model.count}"),
          onPressed: (){model.addCount();},        ),      )
步骤6数据展示

将Consumer包裹在MaterialApp上,数据展示在MaterialApp上的变化,这个也就是Provider在程序入口级别的应用场景

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    Color _themeColor;
    return MultiProvider(                                   //放置监控
      providers: [ChangeNotifierProvider(create: (_) => Counter())],  //数据绑定
      child: Consumer(                                      //数据展示
          builder: (BuildContext context, Counter counter, Widget child) {
        _themeColor = counter.themeColor;
        return MaterialApp(
          debugShowCheckedModeBanner: false,
          theme: ThemeData(
            primaryColor: _themeColor,          ),
          home: MyHome(),        );      }),    );  }}

代码

下面的代码通过测试,在yaml文件中添加依赖,拷贝下面代码后粘贴即可执行使用,第一次运行比较慢,请耐心等待!

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

void main() {
  runApp(MyApp());
  SystemUiOverlayStyle systemUiOverlayStyle =
      SystemUiOverlayStyle(statusBarColor: Colors.transparent);
  SystemChrome.setSystemUIOverlayStyle(systemUiOverlayStyle);            //让状态栏变成透明
}

class Counter with ChangeNotifier {
  int _count = 1;
  Color _themeColor = Colors.redAccent;
  int get value => _count;
  Color get themeColor => _themeColor;
  void addValue() {
    _count++;
    notifyListeners();
  }

  Color changeThemeColor({Color color: Colors.teal}) {
    _themeColor = color;
    notifyListeners();
    return _themeColor;
  }
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    Color _themeColor;
    return MultiProvider(
      providers: [ChangeNotifierProvider(create: (_) => Counter())],
      child: Consumer(
          builder: (BuildContext context, Counter counter, Widget child) {
        _themeColor = counter.themeColor;
        return MaterialApp(
          debugShowCheckedModeBanner: false,
          theme: ThemeData(
            primaryColor: _themeColor,
          ),
          home: MyHome(),
        );
      }),
    );
  }
}

class MyHome extends StatefulWidget {
  @override
  _MyHomeState createState() => _MyHomeState();
}

class _MyHomeState extends State<MyHome> {
  //Counter _counter = new Counter();
  @override
  Widget build(BuildContext context) {
    print('页面重绘了。。。。。。。。。。。');
    return Scaffold(
      appBar: PreferredSize(                                              //用PreferredSize来调整AppBar的高度
        preferredSize: Size.fromHeight(30),
        child: AppBar(
        title: Text("入口级别的Provider演示${Provider.of<Counter>(context).value}"),
        centerTitle: true,
      ),
      ),
      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) {
              return Text(
                //"无",
                "通过Provider.of获取值:${Provider.of<Counter>(context).value}", //没有用consumer包裹的不会自动更新,只有页面重绘时才被更新
                style: TextStyle(fontSize: 20),
              );
            }),
            SizedBox(
              height: 10,
            ),
            RaisedButton(
              color: Colors.blue[200],
              child: Icon(Icons.add),
              onPressed: () {
                print("add");
                Provider.of<Counter>(context, listen: false)
                    .addValue(); //页面级别的使用这个,方法里有notifyListeners();
              },
            ),
            SizedBox(
              height: 10,
            ),
            Consumer(
              builder: (BuildContext context, Counter counter, Widget child) {
                return Text("通过consumer获取的值:${counter.value}",
                    style: TextStyle(fontSize: 20));
              },
            ),
            SizedBox(
              height: 10,
            ),
            RaisedButton(
              color: Colors.green,
              child: Text("主题色变成按钮的颜色"),
              onPressed: () {
                Provider.of<Counter>(context, listen: false)
                    .changeThemeColor(color: Colors.green);
              },
            ),
            SizedBox(
              height: 10,
            ),
            RaisedButton(
              color: Colors.orangeAccent,
              child: Text("主题颜色变成按钮的颜色"),
              onPressed: () {
                Provider.of<Counter>(context, listen: false)
                    .changeThemeColor(color: Colors.orangeAccent);
              },
            ),
          ],
        ),
      ),
    );
  }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值