在使用Provider的時(shí)候,主要關(guān)心三個(gè)概念:
- ChangeNotifier:真正數(shù)據(jù)(狀態(tài))存放的地方
- ChangeNotifierProvider:Widget樹中提供數(shù)據(jù)(狀態(tài))的地方龄砰,會(huì)在其中創(chuàng)建對(duì)應(yīng)的ChangeNotifier
- Consumer:Widget樹中需要使用數(shù)據(jù)(狀態(tài))的地方
代碼:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() {
runApp(MyApp());
}
//^ 1. ChangeNotifier:真正數(shù)據(jù)(狀態(tài))存放的地方
//^ 2. ChangeNotifierProvider:Widget樹中提供數(shù)據(jù)(狀態(tài))的地方趣斤,會(huì)在其中創(chuàng)建對(duì)應(yīng)的ChangeNotifier
//^ 3. Consumer:Widget樹中需要使用數(shù)據(jù)(狀態(tài))的地方
// ! 1. 創(chuàng)建ChangeNotifier,實(shí)際上就是我們的狀態(tài),它不僅存儲(chǔ)了我們的數(shù)據(jù)模型吏奸,還包含了更改數(shù)據(jù)的方法欢揖,并暴露出它想要暴露出的數(shù)據(jù)
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可以獲取到數(shù)據(jù)
//創(chuàng)建頂層共享數(shù)據(jù)奋蔚。這里使用MultiProvider可以創(chuàng)建多個(gè)共享數(shù)據(jù)浸颓,因?yàn)閷?shí)際的應(yīng)用不可能只有一個(gè)數(shù)據(jù)模型
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("第一個(gè)頁面"),
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(
"當(dāng)前計(jì)數(shù):${counterPro.count}",
style: TextStyle(fontSize: 20, color: Colors.red),
);
}),
),
//! 3. Consumer:Widget樹中需要使用數(shù)據(jù)(狀態(tài))的地方
floatingActionButton: Consumer<Counter>(
builder: (ctx, counterPro, child) {
//* ctx: context,上下文,目的是知道當(dāng)前樹的對(duì)象
//* counterPro: ChangeNotifier對(duì)應(yīng)的實(shí)例,也是我們?cè)赽uilder函數(shù)中主要使用的對(duì)象
//* child: 目的是進(jìn)行優(yōu)化旺拉,如果builder下面有一顆龐大的子樹产上,當(dāng)模型發(fā)生改變的時(shí)候,我們并不希望重新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("第二個(gè)頁面"),
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(
"當(dāng)前計(jì)數(shù):${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),
),
);
}
}
file