什么是狀態(tài)管理?
以下僅為本人淺見,如有不對請指出勿噴
狀態(tài)管理就是一些變量的管理,而這些變量需要在多個 路由 界面 中重復使用,所以就有了狀態(tài)管理。
如果多個界面需要重復數(shù)據(jù)時,當這些界面頻繁跳轉(zhuǎn)時,沒有全局狀態(tài)管理,那就需要每次跳轉(zhuǎn) 路由 界面 都需要傳值一次達到保存數(shù)據(jù)的目的,當有了全局狀態(tài)管理,每次需要讀取或者改變這些數(shù)據(jù)時,則可以調(diào)用公用方法獲取或修改,因此可以大大減少工作量并提升應(yīng)用性能
provider入門實戰(zhàn)
本人使用的 provider: ^4.3.2+3,最新為5.0.0,大家可以按需配置依賴
下邊開始用provider實現(xiàn)計數(shù)器
首先創(chuàng)建model類
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
//繼承ChangeNotifier后,可以通知所有訂閱者
class CounterModel with ChangeNotifier {
int _count;//要保存的數(shù)據(jù),我這里實現(xiàn)計數(shù)器,所以只有一個int變量
CounterModel(this._count);
void add() {//提供全局方法,讓全局計數(shù)+1
_count++;
notifyListeners(); //當數(shù)值改變后,通知所有訂閱者刷新ui
}
get count => _count; //提供全局get方法獲取計數(shù)總值
}
修改官方的計數(shù)器代碼
修改Flutter初始項目main.dart
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:provider_demo/provider/Counter.dart';
import 'package:provider_demo/widgets/menu.dart';
void main() {
runApp(
ChangeNotifierProvider(//全局狀態(tài)設(shè)置
create: (context) => CounterModel(0),//創(chuàng)建一個countermodel全局狀態(tài)類,管理count值
child: MyApp(),
),
);
}
//不多做介紹
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Provider'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
actions: [
IconButton(
icon: Icon(Icons.golf_course),
onPressed: () {//創(chuàng)建一個跳轉(zhuǎn)界面,跳轉(zhuǎn)到新的路由,本跳轉(zhuǎn)不傳任何值
Navigator.push(context, MaterialPageRoute(builder: (context) {
return MenuView();
}));
},
),
],
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
//以下代碼Provider.of<model類名>(context).屬性值
//請注意,屬性值在model類中必須有g(shù)et方法
"${Provider.of<CounterModel>(context).count}",
style: Theme.of(context).textTheme.headline4,//字體樣式
),
],
),
),
floatingActionButton: FloatingActionButton(//創(chuàng)建一個懸浮按鈕
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
void _incrementCounter() {//懸浮按鈕點擊事件
//context.read<model類名>().model中的方法;
context.read<CounterModel>().add();
}
}
一個簡單的全局共享就完成了
效果演示

tef5yrq9b8.gif
這時候我們發(fā)現(xiàn),我們沒有傳值更沒有返回值,就能輕松兩個界面管理一個數(shù)據(jù),是不是效率高了很多
但是我們發(fā)現(xiàn),只能全局管理一個狀態(tài),那么怎么管理多個狀態(tài)呢?
很簡單,在main.dart
將
void main() {
runApp(
ChangeNotifierProvider(//全局狀態(tài)設(shè)置
create: (context) => CounterModel(0),//創(chuàng)建一個countermodel全局狀態(tài)類,管理count值
child: MyApp(),
),
);
}
改為
void main() {
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(create: (context) => CounterModel(0)),
//可以繼續(xù)添加,語法如上,這樣可以全局管理多個狀態(tài)
],
child: MyApp(),
),
);
}
總結(jié)
通過簡單demo我們使用了provider演示計數(shù)器,那么在實際開發(fā)中,不會只管理這么簡單的數(shù)據(jù),如果管理數(shù)據(jù)過多,provider就給我們節(jié)省了大量工作量
- 一個model類可以有多個屬性,一個app可以有多個model類
- 全局管理類,不見得用model結(jié)尾,但是我個人喜歡用model來存儲數(shù)據(jù)
- model類必須要繼承ChangeNotifier類,否則無法刷新數(shù)據(jù)
- model管理的狀態(tài),只有get方法,修改他的值是通過單獨的方法進行修改的,在修改后要調(diào)用notifyListeners方法