Flutter使用Provider

1. 使用流程

  1. pubspec.yaml導入工具包并Pub get
  2. 創(chuàng)建provider數(shù)據(jù)模型類
  • 普通數(shù)據(jù)模型UserModel
  • 創(chuàng)建provider模型

注:
創(chuàng)建模型添加變量后生成get和set方法
要在需要監(jiān)聽的方法最后調(diào)用notifyListeners()添加監(jiān)聽

import 'package:flutter/foundation.dart'
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
//注:
// 模型層添加變量
// 生成getter 和 setter方法 (選中類名快捷鍵cmd+n)
// set方法中添加監(jiān)聽
class TestProviderModel with ChangeNotifier,DiagnosticableTreeMixin{
  int _number = 0;
  int get number => _number;
  set number(int value) {
    _number = value;
    notifyListeners();
  }
  void addNumber(){
    _number++;
    notifyListeners();
  }
  // @override
  // void debugFillProperties(DiagnosticPropertiesBuilder properties) {
  //   super.debugFillProperties(properties);
  //   properties.add(IntProperty('number', _number));
  // }
}
  • 如果想要暴露數(shù)據(jù)模型到全局也可如下操作
class UserModel{
  String name;
  String userID;
  bool isAuthor;
  bool isVIP;
  UserModel(this.name, this.userID, this.isAuthor, this.isVIP);
}
import 'package:cayj_cystudio/model/user_model.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
class UserProviderModel with ChangeNotifier,DiagnosticableMixin{
  UserModel _user;
  UserProviderModel(this._user);
  UserModel get user => _user;
  set user(UserModel value) {
    _user = value;
    notifyListeners();
  }
}
  1. app頂層導入provider
  • 封裝一個初始化文件
List<SingleChildWidget> providerList = [
  ChangeNotifierProvider(create: (_)=>TestProviderModel()),
  ChangeNotifierProvider(create: (_)=>UserProviderModel(UserModel("cy", "1", true, true)))
];
  • main函數(shù)中引入使用provider
void main() {
  runApp(
    MultiProvider(
      providers: providerList,
      child: MyApp(),
    ),
  );
}
  1. 使用
class _TestProviderState extends State<TestProvider> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("測試provider"),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ChildOne(),
            ChildTwo()
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.add),
        onPressed: () => context.read<TestProviderModel>().addNumber(),//使用context.read不會調(diào)用rebuild
      )
    );
  }
}


class ChildOne extends StatefulWidget {
  @override
  _ChildOneState createState() => _ChildOneState();
}

class _ChildOneState extends State<ChildOne> {
  @override
  Widget build(BuildContext context) {
    print("1build");
    return Container(
      child: Text("1number = ${context.watch<TestProviderModel>().number}"),
    );
  }
}
class ChildTwo extends StatefulWidget {
  @override
  _ChildTwoState createState() => _ChildTwoState();
}

class _ChildTwoState extends State<ChildTwo> {
  @override
  Widget build(BuildContext context) {
    print("2build");
    // int number = Provider.of<TestProviderModel>(context).number;
    return Container(
      child: Consumer2<TestProviderModel,UserProviderModel>(
        builder: (context,testProvider,userProvider,child){
          return Text("testProviderNumber:${testProvider.number}\n用戶:${userProvider.user.name}");
        },
      )
      // child: Text("當前用戶:${context.watch<UserProviderModel>().user.name}"),
    );
  }
}
  • 簡單的調(diào)用方式
context.watch<TestProviderModel>().number
context.read<TestProviderModel>().addNumber()

如果不希望widget重復(fù)rebuild给猾,可以通過

Widget build(BuildContext context) {
  final name = context.select((Person p) => p.name);
  return Text(name);
}

或者使用Consumer的方式(指揮調(diào)用cosumer內(nèi)部的builder)

return Container(
      child: Consumer2<TestProviderModel,UserProviderModel>(
        builder: (context,testProvider,userProvider,child){
          return Text("testProviderNumber:${testProvider.number}\n用戶:${userProvider.user.name}");
        },
      )
      // child: Text("當前用戶:${context.watch<UserProviderModel>().user.name}"),
    );
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子秉犹,更是在濱河造成了極大的恐慌姆钉,老刑警劉巖褥蚯,帶你破解...
    沈念sama閱讀 216,692評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件国夜,死亡現(xiàn)場離奇詭異鹏控,居然都是意外死亡威始,警方通過查閱死者的電腦和手機枢纠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來黎棠,“玉大人晋渺,你說我怎么就攤上這事镰绎。” “怎么了木西?”我有些...
    開封第一講書人閱讀 162,995評論 0 353
  • 文/不壞的土叔 我叫張陵畴栖,是天一觀的道長。 經(jīng)常有香客問我八千,道長吗讶,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,223評論 1 292
  • 正文 為了忘掉前任恋捆,我火速辦了婚禮照皆,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘沸停。我一直安慰自己纵寝,他們只是感情好,可當我...
    茶點故事閱讀 67,245評論 6 388
  • 文/花漫 我一把揭開白布星立。 她就那樣靜靜地躺著爽茴,像睡著了一般。 火紅的嫁衣襯著肌膚如雪绰垂。 梳的紋絲不亂的頭發(fā)上室奏,一...
    開封第一講書人閱讀 51,208評論 1 299
  • 那天,我揣著相機與錄音劲装,去河邊找鬼胧沫。 笑死,一個胖子當著我的面吹牛占业,可吹牛的內(nèi)容都是我干的绒怨。 我是一名探鬼主播,決...
    沈念sama閱讀 40,091評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼谦疾,長吁一口氣:“原來是場噩夢啊……” “哼南蹂!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起念恍,我...
    開封第一講書人閱讀 38,929評論 0 274
  • 序言:老撾萬榮一對情侶失蹤六剥,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后峰伙,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體疗疟,經(jīng)...
    沈念sama閱讀 45,346評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,570評論 2 333
  • 正文 我和宋清朗相戀三年瞳氓,在試婚紗的時候發(fā)現(xiàn)自己被綠了策彤。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,739評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖店诗,靈堂內(nèi)的尸體忽然破棺而出叽赊,到底是詐尸還是另有隱情,我是刑警寧澤必搞,帶...
    沈念sama閱讀 35,437評論 5 344
  • 正文 年R本政府宣布必指,位于F島的核電站,受9級特大地震影響恕洲,放射性物質(zhì)發(fā)生泄漏塔橡。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,037評論 3 326
  • 文/蒙蒙 一霜第、第九天 我趴在偏房一處隱蔽的房頂上張望葛家。 院中可真熱鬧,春花似錦泌类、人聲如沸癞谒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,677評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至桌吃,卻和暖如春茅诱,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背搬卒。 一陣腳步聲響...
    開封第一講書人閱讀 32,833評論 1 269
  • 我被黑心中介騙來泰國打工契邀, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人椭迎。 一個月前我還...
    沈念sama閱讀 47,760評論 2 369
  • 正文 我出身青樓缴阎,卻偏偏與公主長得像,于是被迫代替她去往敵國和親述暂。 傳聞我的和親對象是個殘疾皇子畦韭,可洞房花燭夜當晚...
    茶點故事閱讀 44,647評論 2 354

推薦閱讀更多精彩內(nèi)容