如果在開發中遇到什麼問題,歡迎加入 flutter興趣交流群 QQ群:541020533
前言
Flutter 用的是 Dart 語言,而 Dart 很多地方借鑑了 React ,比如說每次頁面重新整理用的是和 React 類似的setState
寫法,這樣雖然便於頁面資料的更新,但也帶來了 React 中一直存在的 state
無法跨頁面更新的問題。
React 提供了 Redux , Mobx 等框架來管理頁面狀態和 App 全域性狀態,而閒魚也提供了基於 Redux 的 Fish Redux 用來管理資料的組裝式 Flutter 應用框架。
本文主要講的mobx.dart
是 Mobx 官方推出的,基於 Dart 語言,用來處理 Dart 和 Flutter 狀態的框架。 思路和 Mobx 在 JS 中的用法差不多。作者在開發 React-Native 時用的最多的就是 Mobx, 最近正好在使用 Flutter 重寫開源專案 識兔,所以本文就應運而生。
需求
本文主旨 使用 ,而使用最好的辦法就是實現一個功能。
本文實現一個很簡單的關於跨頁面傳值的功能。
建立三個tab,在第一個tab,做一個模糊的背景圖,在第三個tab,點選按鈕,將第一個tab的背景圖換掉。
準備工作
dependencies:
mobx: 0.3.8+1
flutter_mobx: 0.3.3+1
mobx_codegen: 0.3.9+1 // MobX程式碼生成庫,用來生成 .g.dart的庫
provider: 3.1.0+1 // 全域性狀態管理
複製程式碼
建立Store
為什麼建立Store呢? 因為我們要做的是跨頁面修改狀態,在 Redux 中稱為 Store, 這裡直接借鑑過來。
App可以有多個 Store, 但不推薦每個頁面都是 Store,推薦只有那種需要跨頁面修改狀態的頁面命名為 xxxStore,其他都可以成為 xxxMobx。
shitu_store.dart
import 'package:mobx/mobx.dart'; // 引入
part 'shitu_store.g.dart'; // 稍後會用命令列生成這個檔案,但這裡必須要這麼寫
class ShiTuStore = _ShiTuStore with _$ShiTuStore; // 固定寫法
abstract class _ShiTuStore with Store {
// 預設圖片地址
@observable
String imageUrl =
'http://ww1.sinaimg.cn/large/0065oQSqly1g2pquqlp0nj30n00yiq8u.jpg';
// 外部呼叫,用來修改預設圖片的方法
@action
setImageUrl(String url) {
imageUrl = url;
}
}
複製程式碼
執行命令列
flutter packages pub run build_runner build
複製程式碼
上面寫到了要新增part 'shitu_store.g.dart';
這裡通過這個命令列自動生成該檔案。
通過上面這行命令,會讓 Dart 新增對 @observable
,@computed
, @action
的支援,讓 Mobx 的使用變得簡單。
這部分程式碼,因為是自動生成的,這裡就不貼出來了。需要的可以看開源專案 flutter_shitu
繫結至Provider
這步主要做的是對入口檔案main.dart
的修改,需要引入provider
和shitu_store
;
@override
Widget build(BuildContext context) => MultiProvider(
providers: [ // 陣列,可以注入多個Store
Provider<ShiTuStore>( // 需要更新的Store
builder: (_) => ShiTuStore(),
),
],
child: MaterialApp(
theme: ThemeData(backgroundColor: Colors.white),
home: Scaffold(
resizeToAvoidBottomPadding: false,
body: Launch(),
),
),
);
複製程式碼
業務程式碼
前期準備工作都完成了,接下來就是修改頁面效果了。 這裡先把最重要的程式碼貼出來,最重要,最重要,最重要!
ShiTuStore store = Provider.of<ShiTuStore>(context);
複製程式碼
看到上面的程式碼,有沒有什麼想法? 通過上面的程式碼,就可以在頁面中拿到 Store 中的資料了!
這裡貼出部分程式碼,全部程式碼可以在專案中檢視flutter_shitu。
shitu.dart
body: Stack(
alignment: Alignment.centerLeft,
children: <Widget>[
Image.network(
store.imageUrl, // 通過store得到要展示的圖片
fit: BoxFit.fitHeight,
height: height,
),
BackdropFilter(
filter: ImageFilter.blur(
sigmaX: 5,
sigmaY: 5,
),
child: Container(
color: Colors.white.withOpacity(0.1),
),
),
],
)
複製程式碼
可以發現我這裡用了 Stack
元件,但為什麼用這個? 有興趣的小夥伴可以看我另一個系列的文章
從0到1使用Flutter重構識兔(1)
mine.dart
@override
Widget build(BuildContext context) {
final store = Provider.of<ShiTuStore>(context);
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('我的')),
body: Container(
alignment: Alignment.center,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RaisedButton(
child: Text('點選更改'),
onPressed: () {
// 點選時,呼叫store中的方法切換首頁圖片
store.setImageUrl(
'https://ws1.sinaimg.cn/large/0065oQSqly1g0ajj4h6ndj30sg11xdmj.jpg');
},
)
],
),
),
),
);
}
複製程式碼
總結
主要流程就是 Store => 生成Mobx配置 => Provider => 頁面。
最近在用 Flutter 重寫 識兔專案。
Flutter版識兔也已經開源,稍後會有更多新文章和新功能向大家展示,歡迎star,fork。
從0到1使用Flutter重構識兔系列文章:
如果在開發中遇到什麼問題,歡迎加入 flutter興趣交流群 QQ群:541020533