學習Flutter一段時間了,偶然看到大家都說狀態(tài)管理衍菱,多數(shù)人都是用redux赶么,對于一個Android開發(fā)人員來說之前根本沒接觸過,于是開始了解redux
脊串,之后又了解閑魚推出的fish_redux
,然后又看到Vadaski發(fā)表的一系列關(guān)于Flutter狀態(tài)管理的文章辫呻,包括Scoped Model
, Redux
, BLoC
,RxDart
,provide
(想了解的可以移步),看的是眼花繚亂清钥。對于Redux,能看懂是怎么寫的放闺,但真要到應用的層面循捺,感覺還是有些吃力,更不知道怎樣維護好它雄人,一時間也不知道用什么什么適合自己。后來又接觸到google推薦的Provider念赶,于是學習了下础钠。接下來就用Provider來實現(xiàn)一個計數(shù)的例子。
第一步叉谜,添加Provider依賴
provider: ^2.0.1+1
pub地址:https://pub.dev/packages/provider
第二步旗吁,創(chuàng)建Model
import 'package:provider/provider.dart';
class Counter with ChangeNotifier {//1
int _count;
Counter(this._count);
void add() {
_count++;
notifyListeners();//2
}
get count => _count;//3
}
簡單的一個Counter
對象,里面只有一個字段_count
- 這里需要混入
ChangeNotifier
- 寫一個增加的方法停局,然后需要調(diào)用
notifyListeners();
這個方法是通知用到Counter
對象的widget刷新用的很钓。 -
get
方法
第三步,使用ChangeNotifierProvider
通常main()方法是這么寫
main() {
runApp(MyApp());
}
我們要監(jiān)聽改變就要在MyApp()外面套一層董栽,這個是全局的码倦,于是如下
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
main() {
runApp(ChangeNotifierProvider<Counter>.value(//1
notifier: Counter(1),//2
child: MyApp(),
));
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return MaterialApp(
title: "Provider",
home: HomePage(),
);
}
}
-
ChangeNotifierProvider
調(diào)用value()
方法,里面?zhèn)鞒?code>notifier和child
-
notifier
設置了默認的Counter(1)
當然Provider不止提供了ChangeNotifierProvider
锭碳,還有Provider
,ListenableProvider
,ValueListenableProvider
,StreamProvider
,
具體可以看wiki.
如果想管理多個對象可以用MultiProvider
,如下
MultiProvider(
providers: [
Provider<User>.value(value: user),
Provider<Goods>.value(value: goods),
.....
],
child: someWidget,
)
第四步袁稽,使用Provider獲取Counter的值
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text("Home"),
actions: <Widget>[
FlatButton(
child: Text("下一頁"),
onPressed: () =>
Navigator.push(context, MaterialPageRoute(builder: (context) {
return SecondPage();
})),
),
],
),
body: Center(
child: Text("${Provider.of<Counter>(context).count}"),//1
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Provider.of<Counter>(context).add();//2
},
child: Icon(Icons.add),
),
);
}
}
- 用
Provider.of<Counter>(context).count
獲取_count
的值,Provider.of<T>(context)
相當于Provider去查找它管理的Counter(1)
- 用
Provider.of<Counter>(context).add();
調(diào)用Counter()
中的add()
方法
同樣第二個頁面也這樣寫擒抛,如下
class SecondPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text("SecondPage"),
),
body: Center(
child: Text("${Provider.of<Counter>(context).count}"),//1
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Provider.of<Counter>(context).add();//2
},
child: Icon(Icons.add),
),
);
}
}
這樣推汽,當每個頁面都點擊+號按鈕時,_count
便會+1歧沪,同時通知并更新到使用它的地方歹撒。
完整代碼,copy后可直接運行
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
main() {
runApp(ChangeNotifierProvider<Counter>.value(
notifier: Counter(1),
child: MyApp(),
));
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return MaterialApp(
title: "Provider",
home: HomePage(),
);
}
}
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text("Home"),
actions: <Widget>[
FlatButton(
child: Text("下一頁"),
onPressed: () =>
Navigator.push(context, MaterialPageRoute(builder: (context) {
return SecondPage();
})),
),
],
),
body: Center(
child: Text("${Provider.of<Counter>(context).count}"),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Provider.of<Counter>(context).add();
},
child: Icon(Icons.add),
),
);
}
}
class SecondPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text(Provider.of<String>(context)),
),
body: Center(
child: Text("${Provider.of<Counter>(context).count}"),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Provider.of<Counter>(context).add();
},
child: Icon(Icons.add),
),
);
}
}
class Counter with ChangeNotifier {
int _count;
Counter(this._count);
void add() {
_count++;
notifyListeners();
}
get count => _count;
}
總結(jié)
看了那么多狀態(tài)管理的诊胞,個人感覺Provider還是屬于簡單易用的暖夭,并且是google推薦的。但感覺還需要成長厢钧,讓大家認可鳞尔。我這里只是一個簡單的使用,有一些地方也沒講太清楚還請大家見諒早直,同時也希望和各位學習Flutter的同學互相交流進步寥假。