get 插件官方文檔
get gitbook
get 插件里面有很多有用的功能,大概有下面幾個(gè):
snackbar 消息通知的彈框
dialog 對(duì)話框
bootomsheet
navigation 導(dǎo)航路由
obx 響應(yīng)式狀態(tài)管理(類似 vue, 不用寫 setState 了)
通過 get cli 來創(chuàng)建項(xiàng)目
https://github.com/jonataslaw/get_cli
get cli
安裝:
pub global activate get_cli
get cli 創(chuàng)建項(xiàng)目
get create project:xxx
會(huì)同時(shí)執(zhí)行新建項(xiàng)目和 get init
如果上面的 卡住凳枝,用下面的代替
flutter create project_name
cd project_name
get init
get 快速開始
編輯:pubspec.yaml
dependencies:
get: ^4.1.1
狀態(tài)管理
簡單的狀態(tài)管理器(GetBuilder)和響應(yīng)式狀態(tài)管理器(GetX)
官方計(jì)時(shí)器例子
- 變量控制器controller (繼承 GetxController)
class Controller extends GetxController{
var count = 0.obs;
increment() => count++;
}
- 頁面
使用Getx你可能不再需要使用StatefulWidget碟刺, 直接 StatelessWidget 可以節(jié)省內(nèi)存
// 第一個(gè)頁面
class Home extends StatelessWidget {
@override
Widget build(context) {
// 使用Get.put()實(shí)例化你的類,使其對(duì)當(dāng)下的所有子路由可用除抛。
final Controller c = Get.put(Controller());
return Scaffold(
// 使用Obx(()=>每當(dāng)改變計(jì)數(shù)時(shí)狮杨,就更新Text()。
appBar: AppBar(title: Obx(() => Text("Clicks: ${c.count}"))),
// 用一個(gè)簡單的Get.to()即可代替Navigator.push那8行到忽,無需上下文橄教!
body: Center(child: ElevatedButton(
child: Text("Go to Other"), onPressed: () => Get.to(Other()))),
floatingActionButton:
FloatingActionButton(child: Icon(Icons.add), onPressed: c.increment));
}
}
// 第二個(gè)頁面
class Other extends StatelessWidget {
// 你可以讓Get找到一個(gè)正在被其他頁面使用的Controller,并將它返回給你喘漏。
final Controller c = Get.find();
@override
Widget build(context){
// 訪問更新后的計(jì)數(shù)變量
return Scaffold(body: Center(child: Text("${c.count}")));
}
}
定義響應(yīng)式變量
Controller 類里面定義變量的時(shí)候护蝶,如果聲明一個(gè)可響應(yīng)式的變量有下面幾種方式
- Rx{Type}
final name = RxString('');
final isLogged = RxBool(false);
final count = RxInt(0);
final balance = RxDouble(0.0);
final items = RxList<String>([]);
final myMap = RxMap<String, int>({});
- Rx<Type>
final number = Rx<Num>(0)
final items = Rx<List<String>>([]);
final myMap = Rx<Map<String, int>>({});
// 自定義類 - 可以是任何類
final user = Rx<User>();
- 添加 .obs 作為value的后綴
final number = 0.obs;
final items = <String>[].obs;
final myMap = <String, int>{}.obs;
// 自定義類 - 可以是任何類
final user = User().obs;
如果是 類為 obs, 更新里面的屬性需要 顯式 調(diào)用 refresh 或者 update 方法:
final user = User(name: 'John', last: 'Doe', age: 33).obs;
// `user`是 "響應(yīng)式 "的翩迈,但里面的屬性卻不是!
// 所以持灰,如果我們改變其中的一些變量:
user.value.name = 'Roi';
// 小部件不會(huì)重建!
// 對(duì)于自定義類负饲,我們需要手動(dòng) "通知 "改變堤魁。
user.refresh();
// 或者我們可以使用`update()`方法!
user.update((value){
value.name='Roi';
});
路由導(dǎo)航
普通導(dǎo)航
- 導(dǎo)航到新頁面
Get.to(NextScreen());
- 關(guān)閉頁面
SnackBars、Dialogs返十、BottomSheets, 和任何可以 Navigator.pop(context) 關(guān)閉的東西
Get.back();
- 新頁面妥泉,沒有返回按鈕 (登錄頁面, 歡迎頁面等 不準(zhǔn)用戶返回上個(gè)頁面的)
Get.off(NextScreen());
進(jìn)入下一個(gè)界面并取消之前的所有路由
在購物車、投票和測(cè)試中很有用 洞坑?
Get.offAll(NextScreen());導(dǎo)航到下一條路由盲链,并在返回后立即接收數(shù)據(jù)
// Payment
Get.back(result: 'success');
var data = await Get.to(Payment());
// data result: 'success'
和 原生打開頁面對(duì)比
// 默認(rèn)的Flutter導(dǎo)航
Navigator.of(context).push(
context,
MaterialPageRoute(
builder: (BuildContext context) {
return HomePage();
},
),
);
// get 的導(dǎo)航
Get.to(HomePage());
別名導(dǎo)航
普通導(dǎo)航后面加 Named 就可以啦
需要在 GetMaterialApp 定義 getPages 路由列表(其實(shí)和 MaterialApp 定義的路由差不多)
void main() {
runApp(
GetMaterialApp(
initialRoute: '/',
getPages: [
GetPage(name: '/', page: () => MyHomePage()),
GetPage(name: '/second', page: () => Second()),
GetPage(
name: '/third',
page: () => Third(),
transition: Transition.zoom
),
],
)
);
- 導(dǎo)航到下一個(gè)頁面
Get.toNamed("/NextScreen");
- 打開并刪除前一個(gè)頁面
Get.offNamed("/NextScreen");
- 瀏覽并刪除之前所有的頁面
Get.offAllNamed("/NextScreen");
路由傳參
- 直接是查詢參數(shù):
Get.offAllNamed("/NextScreen?device=phone&id=354&name=Enzo");
另一個(gè)頁面獲取參數(shù):
print(Get.parameters['id']);
// out: 354
print(Get.parameters['name']);
// out: Enzo
- 傳遞 uri 參數(shù)
(uri 里面 用 : 分割 , 類似 gin 里面uri 里面的)
如果有兩個(gè) 比如/profile/
和/profile/:user
短的profile 必須 用/
結(jié)尾
GetPage(
name: '/profile/',
page: () => MyProfile(),
),
//你可以為有參數(shù)的路由定義一個(gè)不同的頁面迟杂,也可以為
沒有參數(shù)的路由定義一個(gè)不同的頁面匈仗,但是你必須在不接收參數(shù)的路由上使用斜杠"/",就像上面說的那樣逢慌。
GetPage(
name: '/profile/:user',
page: () => UserProfile(),
),
上面路由可以下面?zhèn)鲄⒑瞳@取
Get.toNamed("/profile/34954?flag=true");
print(Get.parameters['user']);
print(Get.parameters['flag']);
// out: 34954 true
中間件
中間件通過監(jiān)聽Get事件來觸發(fā)動(dòng)作悠轩,你可以使用routingCallback來實(shí)現(xiàn)
GetMaterialApp(
routingCallback: (routing) {
if(routing.current == '/second'){
openAds();
}
}
)
一些彈框
- SnackBar
函數(shù)簽名
Get.snackbar(
"Hey i'm a Get SnackBar!", // title
"It's unbelievable! I'm using SnackBar without context, without boilerplate, without Scaffold, it is something truly amazing!", // message
icon: Icon(Icons.alarm),
shouldIconPulse: true,
onTap:(){},
barBlur: 20,
isDismissible: true,
duration: Duration(seconds: 3),
);
final snackBar = SnackBar(
content: Text('Hi!'),
action: SnackBarAction(
label: 'I am a old and ugly snackbar :(',
onPressed: (){}
),
);
// 在小組件樹中找到腳手架并使用它顯示一個(gè)SnackBars。
Scaffold.of(context).showSnackBar(snackBar);
上面等價(jià)于
Get.snackbar('Hi', 'i am a modern snackbar');
- Dialogs
Get.dialog(YourDialogWidget());
- BottomSheets
GetView
如果只依賴一個(gè)控制器 GetView 會(huì)簡化開發(fā)攻泼,如果多個(gè)還是按照原來的寫法吧火架。
可以直接寫這樣鉴象,然后就會(huì)有一個(gè) 默認(rèn)的 controller 控制器實(shí)例可以用了
Get.put(Controller());
直接 繼承 GetView<AwesomeController> (要把 自己定義的 controller 寫到模板類型里)
里面直接使用 controller 代指 controller 實(shí)例
class AwesomeController extends GetxController {
final String title = 'My Awesome View';
}
// 一定要記住傳遞你用來注冊(cè)控制器的`Type`!
class AwesomeView extends GetView<AwesomeController> {
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(20),
child: Text( controller.title ), // 只需調(diào)用 "controller.something"。
);
}
}
Bindings
Bindings 主要是配合路由進(jìn)行使用何鸡,當(dāng)通過 GetX 路由進(jìn)入頁面時(shí)纺弊,會(huì)自動(dòng)調(diào)用 dependencies 方法。 可以方便的幫我們做一些 接口 請(qǐng)求初始化的操作骡男, 然后在 controller 里面就非常方便的使用 請(qǐng)求了淆游。重點(diǎn)是 代碼結(jié)構(gòu)清晰。
Page 中就能正常使用 Get.find ( GetView 的可以直接 controller 也可以 find )獲取到注入的 Controller 對(duì)象
就不用寫 get.put() 了
binding 多個(gè) Controller 隔盛,可以依次通過 find 獲取實(shí)例
final HomeController1 c = Get.find();
final HomeController c = Get.find();
或者
Get.find<HomeController1 >().
可以看到只要傳指定的類型犹菱,find 就可以獲對(duì)應(yīng)的 實(shí)例
關(guān)于 get cli 進(jìn)階使用
https://1467602180.github.io/flutter-getx-doc/engineer/advanced#%E4%BD%BF%E7%94%A8
遇到的問題
就是我需要修改某個(gè) obs 屬性,一開始沒有 用 Obx 來包裝吮炕,導(dǎo)致樣式不對(duì)腊脱,后來用Obx 包裝一下就好了。就是說龙亲,如果一個(gè)組件和 obs 屬性關(guān)聯(lián)陕凹,那要用 Obx 包裝才能起到響應(yīng)式改變
Scaffold(
//bottomNavigationBar 雖然沒用到 controller.select_index ,但是要重新渲染就要用 Obx 修改鳄炉, 因?yàn)閎ottomNavigationBar 用到了 currentIndex杜耙, 也就是Obx 的屬性。
bottomNavigationBar: Obx(() => BottomNavigationBar(
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(icon: Icon(Icons.home), label: '首頁'),
BottomNavigationBarItem(icon: Icon(Icons.business), label: '發(fā)現(xiàn)'),
BottomNavigationBarItem(icon: Icon(Icons.school), label: '個(gè)人中心'),
],
currentIndex: controller.select_index.value,
selectedItemColor: Colors.teal,
onTap: (int index){ controller.select_index.value = index; },
)),
body: Obx(() => tab_widget[controller.select_index.value])
);
響應(yīng)式屬性:
設(shè)置屬性和獲取屬性拂盯,如果是響應(yīng)式的都要 .value 不然可能不會(huì)做到響應(yīng)和屬性綁定佑女。