Provider的幾種使用方式
1冰单、Provider
描述:是為恒定的數(shù)據(jù)提供的方法(類)。當(dāng)一個(gè)widget只是從這個(gè)model中取數(shù)據(jù)灸促,而不去監(jiān)聽數(shù)據(jù)的變化而去重繪界面.
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class MyModel {
MyModel({this.counter = 0});
int counter = 0;
void incrementCounter() {
counter++;
print(counter);
}
}
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
print("build方法來了");
return Provider(
create: (_) => MyModel(),
child: Scaffold(
appBar: AppBar(
title: Text('provider'),
),
body: Column(
children: <Widget>[
Builder(
builder: (context) {
// 獲取到provider提供出來的值
MyModel _model = Provider.of<MyModel>(context, listen: false);
return Container(
margin: const EdgeInsets.only(top: 20),
width: MediaQuery.of(context).size.width,
padding: const EdgeInsets.all(20),
alignment: Alignment.center,
color: Colors.lightBlueAccent,
child: Text('當(dāng)前是:${_model.counter}'));
},
),
Consumer<MyModel>(
// 獲取到provider提供出來的值
builder: (context, model, child) {
return Container(
margin: const EdgeInsets.only(top: 20),
width: MediaQuery.of(context).size.width,
padding: const EdgeInsets.all(20),
alignment: Alignment.center,
color: Colors.lightGreen,
child: Text(
'${model.counter}',
),
);
},
),
Consumer<MyModel>(
// 獲取到provider提供出來的值
builder: (context, model, child) {
return FlatButton(
color: Colors.tealAccent,
onPressed: model.incrementCounter,
child: Icon(Icons.add));
},
),
],
),
),
);
}
}
2诫欠、ListenableProvider和ChangeNotifierProvider
描述:當(dāng)model對(duì)像中有數(shù)據(jù)變化時(shí)涵卵,需要觸發(fā)widget中的元素重繪,實(shí)現(xiàn)數(shù)據(jù)驅(qū)動(dòng)荒叼,這時(shí)我們需要用到ChangeNotifierProvider轿偎。
import 'package:flutter/material.dart';
import 'package:flutterproviderapp/detailPage.dart';
import 'package:provider/provider.dart';
import 'Models.dart';
class MyHomePage2 extends StatelessWidget {
@override
Widget build(BuildContext context) {
print("MyHomePage2的build方法來了");
return ListenableProvider(
/* ListenableProvider和ChangeNotifierProvider幾乎是一樣的效果,只是ListenableProvider比ChangeNotifierProvider多了個(gè)_dispose函數(shù)被廓,
會(huì)在適當(dāng)?shù)臅r(shí)候自動(dòng)銷毀坏晦,一般情況下只用changeNotifierProvider即可。
*/
create: (_) => MyModel(),
child: Scaffold(
appBar: AppBar(
title: Text('ChangeNotifierProvider'),
),
body: Column(
children: <Widget>[
Builder(
builder: (context) {
// 獲取到provider提供出來的值
MyModel _model = Provider.of<MyModel>(context, listen: false);
return Container(
margin: const EdgeInsets.only(top: 20),
width: MediaQuery.of(context).size.width,
padding: const EdgeInsets.all(20),
alignment: Alignment.center,
color: Colors.lightBlueAccent,
child: Text('當(dāng)前是:${_model.counter}'));
},
),
Consumer<MyModel>(
// 獲取到provider提供出來的值
child: Container(
// consumer 里的child的組件是不會(huì)被渲染的嫁乘,builder里的組件是會(huì)被重新渲染的
margin: const EdgeInsets.only(top: 20),
width: MediaQuery.of(context).size.width,
padding: const EdgeInsets.all(20),
alignment: Alignment.center,
color: Colors.lightGreen,
child: Text(
'hhhhhhhhhhh',
),
),
builder: (context, model, child) {
print("Consumer里的builder來了");
return Column(
children: <Widget>[
child!,
Container(
margin: const EdgeInsets.only(top: 20),
width: MediaQuery.of(context).size.width,
padding: const EdgeInsets.all(20),
alignment: Alignment.center,
color: Colors.lightGreen,
child: Text(
'${model.counter}',
),
)
],
);
},
),
MyText(),
MyText2(),
Consumer<MyModel>(
// 獲取到provider提供出來的值
builder: (context, model, child) {
return FlatButton(
color: Colors.tealAccent,
onPressed: model.incrementCounter,
child: Icon(Icons.add));
},
),
],
),
),
);
}
}
// 初始化一個(gè)單獨(dú)的子部件套進(jìn)去昆婿,看能不能用provider.of(context)獲取model
class MyText extends StatelessWidget {
@override
Widget build(BuildContext context) {
print("MyText子部件的build方法來了");
MyModel _model =
Provider.of<MyModel>(context); // 這里的也能正常拿到Provider中的model的,因?yàn)槭枪蚕淼摹? return Container(
child: Text('當(dāng)前是MyText里的:${_model.counter}'),
);
}
}
class MyText2 extends StatelessWidget {
@override
Widget build(BuildContext context) {
print("MyText2子部件的build方法來了");
MyModel models =
Provider.of<MyModel>(context); // 這里的也能正常拿到Provider中的model的蜓斧,因?yàn)槭枪蚕淼摹? return Container(
child: FlatButton(
color: Colors.tealAccent,
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(builder: (context) {
return DiscoverDetailPage(models);
}));
},
child: Icon(Icons.ac_unit)),
);
}
}
例子中使用到的model
import 'package:flutter/material.dart';
class MyModel with ChangeNotifier {
MyModel({this.counter = 0});
int counter = 0;
void incrementCounter() {
counter++;
print(counter);
notifyListeners();
}
}
3仓蛆、StreamProvider
描述:可以給StreamProvider提供一份初始的數(shù)據(jù)Model,通過給StreamProvider設(shè)置了一個(gè)每隔1秒更新一次的stream挎春,ui上的計(jì)數(shù)值也是每隔一秒改變一次看疙。
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class MyModel with ChangeNotifier {
MyModel({this.counter = 0});
int counter = 0;
void incrementCounter() {
counter++;
print(counter);
notifyListeners();
}
}
class MyHomePage4 extends StatelessWidget {
Stream<MyModel> getStreamProviderData(BuildContext context) {
print("getStreamProviderData方法");
return Stream<MyModel>.periodic(Duration(seconds: 1), getMyModel);
}
MyModel getMyModel(int count) {
print("getMyModel方法");
count++;
if (count > 60) {
return MyModel(counter: 60);
}else {
return MyModel(counter: count);
}
}
@override
Widget build(BuildContext context) {
print("build方法來了");
return StreamProvider(
initialData: MyModel(counter: 0),
create: getStreamProviderData, // 當(dāng)這個(gè)函數(shù)執(zhí)行的時(shí)候,會(huì)渲染UI
child: Scaffold(
appBar: AppBar(
title: Text('FutureProvider'),
),
body: Column(
children: <Widget>[
Builder(builder: (context) {
MyModel _model = Provider.of<MyModel>(context);
return Container(
margin: const EdgeInsets.only(top: 20),
width: MediaQuery.of(context).size.width,
padding: const EdgeInsets.all(20),
alignment: Alignment.center,
color: Colors.lightBlueAccent,
child: Text('當(dāng)前是:${_model.counter}'),
);
}),
Consumer<MyModel>(builder: (context, model, child) {
return Container(
margin: const EdgeInsets.only(top: 20),
width: MediaQuery.of(context).size.width,
padding: const EdgeInsets.all(20),
alignment: Alignment.center,
color: Colors.lightGreen,
child: Text(
'${model.counter}',
),
);
}),
Consumer<MyModel>(builder: (context, model, child) {
return FlatButton(
color: Colors.tealAccent,
onPressed: model.incrementCounter,
child: Icon(Icons.add));
}),
],
),
));
}
}
4直奋、MultiProvider
描述:可以組合Provider所提供的類能庆,給Ui提供多個(gè)數(shù)據(jù)Model。
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class MyHomePage5 extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider<BannerModel>(create: (context) => BannerModel()),
ChangeNotifierProvider<ListModel>(create: (context) => ListModel()),
],
child: Scaffold(
appBar: AppBar(
title: Text('provider'),
),
body: Column(
children: <Widget>[
Builder(
builder: (context) {
BannerModel modol = Provider.of<BannerModel>(context);
return Container(
margin: const EdgeInsets.only(top: 20),
width: MediaQuery.of(context).size.width,
padding: const EdgeInsets.all(20),
alignment: Alignment.center,
color: Colors.lightBlueAccent,
child: Text('當(dāng)前Banner有幾個(gè):${modol.counter}'));
},
),
Consumer<ListModel>(
builder: (context, model, child) {
return Container(
margin: const EdgeInsets.only(top: 20),
width: MediaQuery.of(context).size.width,
padding: const EdgeInsets.all(20),
alignment: Alignment.center,
color: Colors.lightGreen,
child: Text(
'當(dāng)前Banner有幾個(gè):${model.counter}',
),
);
},
),
Consumer<BannerModel>(
builder: (context, model, child) {
return FlatButton(
color: Colors.tealAccent,
onPressed: model.getBanner,
child: Text("獲取banner"));
},
),
Consumer<ListModel>(
builder: (context, model, child) {
return FlatButton(
color: Colors.tealAccent,
onPressed: model.getList,
child: Text("獲取列表"));
},
),
],
),
),
);
}
}
class BannerModel with ChangeNotifier {
int counter = 0;
Future<void> getBanner() async {
await Future.delayed(Duration(microseconds: 500));
counter++;
notifyListeners();
print(counter);
}
}
class ListModel with ChangeNotifier {
int counter = 0;
Future<void> getList() async {
await Future.delayed(Duration(microseconds: 500));
counter++;
notifyListeners();
print(counter);
}
}
5帮碰、ProxyProvider
描述:當(dāng)一個(gè)model依賴另一個(gè)model時(shí)相味,就以用ChangeNotifierProxyProvider把依賴的model推給被依賴model對(duì)像拾积。當(dāng)前例子模擬的是picmodel成功后殉挽,submitmodel才能成功。(場(chǎng)景:點(diǎn)擊提交按鈕的時(shí)候拓巧,先圖片上傳斯碌,成功了頁面才提交成功)
import 'package:provider/provider.dart';
import 'package:flutter/material.dart';
class MyHomePage6 extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider<PicModel>(create: (context) => PicModel()),
ProxyProvider<PicModel, SubmitModel>(
update: (context, myModel, anotherModel) => SubmitModel(myModel),
),
],
child: Scaffold(
appBar: AppBar(
title: Text('provider'),
),
body: Column(
children: <Widget>[
Builder(
builder: (context) {
PicModel modol = Provider.of<PicModel>(context);
return Container(
margin: const EdgeInsets.only(top: 20),
width: MediaQuery.of(context).size.width,
padding: const EdgeInsets.all(20),
alignment: Alignment.center,
color: Colors.lightBlueAccent,
child: Text('提交圖片:${modol.counter}'));
},
),
Consumer<PicModel>(
builder: (context, model, child) {
return FlatButton(
color: Colors.tealAccent,
onPressed: model.upLoadPic,
child: Text("提交圖片"));
},
),
Consumer<SubmitModel>(
builder: (context, model, child) {
return FlatButton(
color: Colors.tealAccent,
onPressed: () {
model.subMit().then((value) {
print("頁面提交成功!");
});
},
child: Text("提交頁面"));
},
),
],
),
),
);
}
}
class PicModel with ChangeNotifier {
int counter = 0;
Future<void> upLoadPic() async {
// counter++;
// notifyListeners();
await Future.delayed(Duration(seconds: 2));
counter++;
notifyListeners();
print(counter);
print("圖片提交成功");
}
}
class SubmitModel {
PicModel _model;
SubmitModel(this._model);
Future<void> subMit() async {
await _model.upLoadPic();
}
}
點(diǎn)擊下載demo
如果對(duì)您有用的話肛度,點(diǎn)贊鼓勵(lì)一下傻唾!