Provider
封裝了 InheritedWidget
功能,提供更高效且易懂的使用方式。
引言 Provider
說明文件
By using provider instead of manually writing InheritedWidget, you get:
- simplified allocation/disposal of resources
- lazy-loading
- a vastly reduced boilerplate over making a new class every time
- friendly to devtools
- a common way to consume these InheritedWidgets (See Provider.of/Consumer/> Selector)
- increased scalability for classes with a listening mechanism that grows > exponentially in complexity (such as ChangeNotifier, which is O(N) for > dispatching notifications).
在StatefullWidget
中我們可以透過State
處理一個Widget
的狀態管理,但是實務上在應用程式的開發過程裡往往會需要一個全局性的狀態管理的解決方案,在官網這邊有提供其他選項讓開發人員自己選擇理想的套件,而 Provider
是 Google 官方建議使用的第三方套件。
Provider
:Provider
套件根據資料來源的不同提供多種 Provder
組件處理不同資料的供應來源Consumer
:使用Consumer
組件的builder
的方式取得資料Selector
:類似Consumer
,對於複雜資料源提供更進階的取用方式of
:組件內部使用BuildContext
的of
方法取得資料ChangeNotifier
:Flutter SDK 內部的 mixin 類別,用來實現「觀察者模式」的方法先前在介紹 Widget狀態管理章節時我們有完成一個顯示時間更新的範例,今天我們就使用 Provider
來改寫看看吧。
內部提供多個組件處理不同的資料來源
原本範例中自定義的TimeModel
類別實現ChangeNotifier
功能,我們可以在使用ChangeNotifierProvider
定義資料來源
class ProviderScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("Provider")),
body: ChangeNotifierProvider(
create: (context) => TimeModel(),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
TimeConsumerWidget(),
TimeOfWidget(),
],
),
),
),
);
}
}
class TimeConsumerWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Consumer<TimeModel>(
builder: (context, time, child) {
return Text("Consumer: ${time.toString()}");
},
);
}
}
class TimeOfWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
var time = Provider.of<TimeModel>(context);
return Text("of(): ${time.toString()}");
}
}
;