Flutter 狀態管理 Provider

Flutter 狀態管理,實際來說就是數據和視圖的綁定和刷新;
這塊對應到 H5,就比較好理解,這個概念也是從前端來到;
對應到 客戶端,就是監聽回調,類似事件總線(EventBus);

Provider 基本使用:
  • 建議在 main 方法加上這段代碼,防止熱重載報錯,如果還是報錯就必須點擊下 run 按鈕了;
void main() {
  WidgetsFlutterBinding.ensureInitialized();
  Provider.debugCheckInvalidValueType = null;
  ......
}
  • 創建 Model,繼承 ChangeNotifier;
class ATheme with ChangeNotifier {
  double textSize = 16;
  int bgColor = 0xffff0000;
  int textColor = 0xff666666;

  void setTheme(int bgColor) {
    textSize = 18;
    this.bgColor = bgColor;
    textColor = 0xff333333;
    // 調用這個方法,通知所有監聽
    notifyListeners();
  }
}
  • 創建共享數據;
void main() {
  WidgetsFlutterBinding.ensureInitialized();
  Provider.debugCheckInvalidValueType = null;
  runApp(
    MultiProvider(
      providers: [
        ChangeNotifierProvider.value(value: new ATheme()),
        ChangeNotifierProvider.value(value: new LoginInfo()),
      ],
      child: MaterialApp(
        home: StartPage(),
      ),
    ),
  );
}
  • 綁定和刷新數據;
class ThemeChangePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // 注意在 build 裏面調用 Provider.of<ATheme>(context); 就會自動註冊監聽;也不用擔心重複註冊;
    ATheme appTheme = Provider.of<ATheme>(context);
    LoginInfo loginInfo = Provider.of<LoginInfo>(context);
    return Scaffold(
      // 這裏可以直接使用 model 的屬性了,如果有變化會自動刷新
      backgroundColor: Color(appTheme.bgColor),
      appBar: AppBar(
        title: Text("改變主題 ${loginInfo.name}"),
      ),
      body: Column(
        children: <Widget>[
          FlatButton(
            onPressed: () {
              appTheme.setTheme(0xffff00ff);
            },
            child: Text("紅"),
          ),
          FlatButton(
            onPressed: () {
              appTheme.setTheme(0xff00ffff);
            },
            child: Text("黃"),
          ),
          FlatButton(
            onPressed: () {
              appTheme.setTheme(0xff0000ff);
            },
            child: Text("藍"),
          ),
        ],
      ),
    );
  }
}
如果我只是想要監聽回調,比如登陸後跳轉到某個頁面;
class LoginInfoManager with ChangeNotifier {
  static LoginInfoManager instance = LoginInfoManager();

  String id = "沒信息ID";
  String name = "沒信息name";

  void setLoginInfo() {
    id = "測試ID";
    name = "測試名稱";
    notifyListeners();
  }
}
class _StartPageState extends State<StartPage> {
  @override
  void initState() {
    super.initState();
    // 手動添加監聽
    LoginInfoManager.instance.addListener(onLoginChanged);
  }

  void onLoginChanged() {
    LoginInfoManager loginInfo = LoginInfoManager.instance;
    print("${loginInfo.name}");
  }

  @override
  void dispose() {
  	// 手動移除監聽
    LoginInfoManager.instance.removeListener(onLoginChanged);
    super.dispose();
  }
  
}
總結
  • 本身使用是很簡單的;
  • 簡化了監聽回調,實際是內部自動註冊監聽了;
  • 注意局部使用 Provider;並不是所有數據都要放在 main 裏面,放到使用到數據的頂層就行了;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章