iT邦幫忙

2021 iThome 鐵人賽

DAY 20
0
Mobile Development

Flutter / Dart 跨平台App開發體驗系列 第 20

Flutter體驗 Day 20-Provider

Provider

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 官方建議使用的第三方套件。

重要元件

  • ProviderProvider套件根據資料來源的不同提供多種 Provder 組件處理不同資料的供應來源
  • Consumer:使用Consumer組件的builder 的方式取得資料
  • Selector:類似Consumer,對於複雜資料源提供更進階的取用方式
  • of:組件內部使用BuildContextof方法取得資料
  • ChangeNotifier:Flutter SDK 內部的 mixin 類別,用來實現「觀察者模式」的方法

範例

先前在介紹 Widget狀態管理章節時我們有完成一個顯示時間更新的範例,今天我們就使用 Provider 來改寫看看吧。

  • Providers

內部提供多個組件處理不同的資料來源

  1. ChangeNotifierProvider
  2. ValueNotifier
  3. MultiProvider
  4. ProxyProvider
  5. FutureProvider
  6. StreamProvider

原本範例中自定義的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(),
            ],
          ),
        ),
      ),
    );
  }
}
  • Consumer builder() 取用方式
class TimeConsumerWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Consumer<TimeModel>(
      builder: (context, time, child) {
        return Text("Consumer: ${time.toString()}");
      },
    );
  }
}
  • of() 取用方式
class TimeOfWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    var time = Provider.of<TimeModel>(context);
    return Text("of(): ${time.toString()}");
  }
}

widget_provider;

小結

練習成果


上一篇
Flutter體驗 Day 19-InheritedWidget
下一篇
Flutter體驗 Day 21-Http
系列文
Flutter / Dart 跨平台App開發體驗30

尚未有邦友留言

立即登入留言