用了兩年的flutter紧帕,有了一些心得盔然,不虛頭巴腦,只求實戰(zhàn)有用是嗜,以供學習或使用flutter的小伙伴參考轻纪,學習尚淺,如有不正確的地方還望各路大神指正叠纷,以免誤人子弟刻帚,在此拜謝~(原創(chuàng)不易,轉發(fā)請標注來源和作者)
注意:無特殊說明涩嚣,flutter版本為3.0+
講完了基礎工具的封裝崇众,那么我們從今天來看下實戰(zhàn)中如何組織項目結構。
一.什么是Getx
兩年多以前航厚,決定使用Flutter對舊項目進行改造時候顷歌,在諸多Flutter框架中(當時有比較流行的Provider狀態(tài)管理框架,咸魚開源Fish Redux和BloC)選擇了尚不成熟的Getx幔睬,當時的Github的star量只有幾百和使用人數(shù)都相對較少(現(xiàn)在Getx的star超過7.3k)眯漩,算是見證了它的成長,可見是金子總會被發(fā)現(xiàn)。
GetX 是 Flutter 上的一個輕量且強大的解決方案:高性能的狀態(tài)管理赦抖、智能的依賴注入和便捷的路由管理舱卡。這些也是它的特色
廢話不多說,我們看下如何在實戰(zhàn)中使用Getx队萤。
二.使用Getx進行路由管理
Getx提供了一個GetMaterialApp轮锥,這個是對MaterialApp的一個封裝,可以便捷的配置項目要尔,我們通常這樣使用
GetMaterialApp(
onInit: () async {
//項目初始化進行配置
},
debugShowCheckedModeBanner: false,
// theme: appThemeData,
locale: const Locale('zh', 'CN'),
fallbackLocale: const Locale('en', 'US'),
// 添加一個回調語言選項舍杜,以備上面指定的語言翻譯不存在
defaultTransition: Transition.rightToLeft,
getPages: Pages.pages,
localizationsDelegates: const [
GlobalMaterialLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
supportedLocales: const [Locale('en', 'US'), Locale('zh', 'CN')],
initialRoute: Routes.splashPage,
navigatorObservers: [FlutterSmartDialog.observer],
builder: FlutterSmartDialog.init(
toastBuilder: (String msg) {
return customToastWidget(msg);
},
loadingBuilder: (String msg) {
return customLoadingWidget(msg);
},
),
)
其中有getPages和initialRoute,我么知道一個配置項目所有路由頁面赵辕,一個是項目初始化跳轉的頁面既绩,一般是閃屏頁。
我們知道通常app有非常多的頁面还惠,那么怎么更好的組織頁面呢熬词?我們可以根據(jù)模塊進行頁面劃分。所以我們的Pages可以這樣拆寫
abstract class AppPages {
static final pages = [
...UsersPages.pages,//用戶相關頁面
...OrdersPages.pages,//訂單相關頁面
...GoodsPages.pages,//商品相關頁面
...CustomerPages.pages,//客戶相關頁面
...
];
}
那么在新建的頁面中,例如UserPages中可以這樣寫吸重,那么就把路由拆解開來了
abstract class UsersPages {
static final pages = [
GetPage(
name: Routes.splashPage,
page: () => SplashView(),
binding: SplashBinding(),
),
GetPage(
name: Routes.login,
page: () => LoginView(),
binding: LoginBinding(),
)}
三.使用Getx Bindings依賴注入
不管是寫web前端互拾,還是Android或者ios,面對復雜的頁面我們都希望頁面(UI)和實現(xiàn)(邏輯)進行分離嚎幸,那么常用的模式有MVC颜矿,MVVM等進行抽離,那么在Flutter中我們可以用同樣的方式組織項目嫉晶。
如上圖骑疆,一個閃屏頁面,我們分為bingdings替废,controllers箍铭,views,widget椎镣。
bingdings:綁定controller诈火,動態(tài)注入
controllers:頁面的邏輯實現(xiàn)
views:頁面的主要UI
widget:頁面用到的組件,頁面比較復雜時候抽離出來的組件
四.使用Getx進行狀態(tài)管理
1.如果你監(jiān)聽的是一個值的改變状答,那么ObxValue就是一個神器
RxInt count = 0.obs;
當count改變的時候冷守,頁面中使用
Obx(()=>Text(count.value))
就可以直接刷新頁面
2.GetBuilder
GetBuilder<TestController>(
id: 'count',
builder: (ctl) {return Text(ctl.count);
}
那么只需要在count改變的時候使用
update(['count'])
看源碼我們知道,update的底層的實現(xiàn)原理惊科,就是實現(xiàn)了ValueListenable拍摇,ChangeNotifier,ValueNotifier
/// An object that maintains a list of listeners.
///
/// The listeners are typically used to notify clients that the object has been
/// updated.
///
/// There are two variants of this interface:
///
/// * [ValueListenable], an interface that augments the [Listenable] interface
/// with the concept of a _current value_.
///
/// * [Animation], an interface that augments the [ValueListenable] interface
/// to add the concept of direction (forward or reverse).
///
/// Many classes in the Flutter API use or implement these interfaces. The
/// following subclasses are especially relevant:
///
/// * [ChangeNotifier], which can be subclassed or mixed in to create objects
/// that implement the [Listenable] interface.
///
/// * [ValueNotifier], which implements the [ValueListenable] interface with
/// a mutable value that triggers the notifications when modified.
///
/// The terms "notify clients", "send notifications", "trigger notifications",
/// and "fire notifications" are used interchangeably.
///
/// See also:
///
/// * [AnimatedBuilder], a widget that uses a builder callback to rebuild
/// whenever a given [Listenable] triggers its notifications. This widget is
/// commonly used with [Animation] subclasses, hence its name, but is by no
/// means limited to animations, as it can be used with any [Listenable]. It
/// is a subclass of [AnimatedWidget], which can be used to create widgets
/// that are driven from a [Listenable].
/// * [ValueListenableBuilder], a widget that uses a builder callback to
/// rebuild whenever a [ValueListenable] object triggers its notifications,
/// providing the builder with the value of the object.
/// * [InheritedNotifier], an abstract superclass for widgets that use a
/// [Listenable]'s notifications to trigger rebuilds in descendant widgets
/// that declare a dependency on them, using the [InheritedWidget] mechanism.
/// * [Listenable.merge], which creates a [Listenable] that triggers
/// notifications whenever any of a list of other [Listenable]s trigger their
/// notifications.
abstract class Listenable {