本系列同步發表在 個人部落格,歡迎大家關注~
今天就開始來使用 Provider 來改動一下頁面囉~
首先要被我拿來實驗的頁面(們),就是登入/首頁的部份。
實驗的步驟則是參照官方文件教學 Simple app state management
官方範例是用一個簡單的購物及購物車 App,非常推薦可以閱讀它來理解狀態管理。
這是官方教學的第一步驟,就是將分散在子孫節點的狀態(State),匯集在最上面的節點。
如下圖
對應 Gitme Reborn App 首先就是需要將帳戶資訊作集中管理。
lib/stores/account.dart
import 'package:flutter/foundation.dart';
import 'package:github/server.dart';
import 'package:gitme_reborn/services/github_api.dart';
class AccountModel extends ChangeNotifier {
CurrentUser _user;
List<Repository> _repos;
List<Issue> _issues;
CurrentUser get profile => _user;
List<Repository> get repos => _repos;
List<Issue> get issues => _issues;
...
void updateUser(CurrentUser user) {
_user = user;
notifyListeners();
}
...
}
AccountModel
裡。ChangeNotifier
是必須的,用來使 AccountModel
有被其子孫節點註冊監聽的能力。有了狀態(AccountModel
)跟註冊監聽(ChangeNotifier
),就剩下如何「提供通知」和「獲取狀態」。
而「提供通知」,照字面上就要有個提供者,也就是這套件的名稱 provider。
通常需要先知道是哪一部分的子孫節點們用到這些狀態,不過很大部份都會把 Provider 放在最上層,以提供整個 App 的狀態作管理。
main.dart 裡,在 GitmeRebornApp
外面包一層 MultiProvider
,在 providers
參數填入數值。
最後就是「獲取狀態」,有兩種基本方式
Provider.of
MainPage.build
宣告 var account = Provider.of<AccountModel>(context);
,之後在 MainPage
裡就能使用 account.xxx
來獲取狀態囉~
Consumer
參考 Commit 使用方式
小提醒:
- 在
RepoPage
和IssuePage
內基本上已經不用 StatefulWidget 了,所有的狀態都被我搬到AccountModel
集中管理;不過改回 StatelessWidget 有些麻煩,所以就不改囉~- 在
RepoPage
和IssuePage
內,會檢查狀態裡有沒有從 API 獲取過的資料,如果沒有或重新 Refresh 才會再次撈取- 記得使用 Provider 需要在
pubspec.yaml
裡加入provider: ^3.1.0
--
成果