GetX 路由管理

https://gitee.com/frontend-qin/getx/blob/master/documentation/zh_CN/route_management.md

路由管理

這是關(guān)于Getx在路由管理方面的完整解釋柳洋。

如何使用

將此添加到你的pubspec.yaml文件中正卧。

dependencies:
  get:

如果你要在沒有context的情況下使用路由/SnackBars/Dialogs/BottomSheets颜阐,或者使用高級的Get API,你只需要在你的MaterialApp前面加上 "Get"掉丽,就可以把它變成GetMaterialApp跌榔,享受吧!

GetMaterialApp( // Before: MaterialApp(
  home: MyHome(),
)

普通路由導(dǎo)航

導(dǎo)航到新的頁面。

Get.to(NextScreen());

關(guān)閉SnackBars捶障、Dialogs僧须、BottomSheets或任何你通常會用Navigator.pop(context)關(guān)閉的東西。

Get.back();

進入下一個頁面残邀,但沒有返回上一個頁面的選項(用于SplashScreens皆辽,登錄頁面等)。

Get.off(NextScreen());

進入下一個界面并取消之前的所有路由(在購物車芥挣、投票和測試中很有用)驱闷。

Get.offAll(NextScreen());

要導(dǎo)航到下一條路由,并在返回后立即接收或更新數(shù)據(jù)空免。

var data = await Get.to(Payment());

在另一個頁面上空另,發(fā)送前一個路由的數(shù)據(jù)。

Get.back(result: 'success');

并使用它蹋砚,例:

if(data == 'success') madeAnything();

你不想學(xué)習(xí)我們的語法嗎扼菠?
只要把 Navigator(大寫)改成 navigator(小寫)摄杂,你就可以擁有標準導(dǎo)航的所有功能,而不需要使用context循榆,例如:


// 默認的Flutter導(dǎo)航
Navigator.of(context).push(
  context,
  MaterialPageRoute(
    builder: (BuildContext context) {
      return HomePage();
    },
  ),
);

// 使用Flutter語法獲得析恢,而不需要context。
navigator.push(
  MaterialPageRoute(
    builder: (_) {
      return HomePage();
    },
  ),
);

// get語法 (這要好得多)
Get.to(HomePage());


別名路由導(dǎo)航

  • 如果你喜歡用別名路由導(dǎo)航秧饮,Get也支持映挂。

導(dǎo)航到下一個頁面

Get.toNamed("/NextScreen");

瀏覽并刪除前一個頁面。

Get.offNamed("/NextScreen");

瀏覽并刪除所有以前的頁面盗尸。

Get.offAllNamed("/NextScreen");

要定義路由柑船,使用GetMaterialApp。

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)航(404錯誤)泼各,可以在GetMaterialApp中定義unknownRoute頁面鞍时。

void main() {
  runApp(
    GetMaterialApp(
      unknownRoute: GetPage(name: '/notfound', page: () => UnknownRoutePage()),
      initialRoute: '/',
      getPages: [
        GetPage(name: '/', page: () => MyHomePage()),
        GetPage(name: '/second', page: () => Second()),
      ],
    )
  );
}

發(fā)送數(shù)據(jù)到別名路由

只要發(fā)送你想要的參數(shù)即可。Get在這里接受任何東西扣蜻,無論是一個字符串逆巍,一個Map,一個List莽使,甚至一個類的實例蒸苇。

Get.toNamed("/NextScreen", arguments: 'Get is the best');

在你的類或控制器上:

print(Get.arguments);
//print out: Get is the best

動態(tài)網(wǎng)頁鏈接

Get提供高級動態(tài)URL,就像在Web上一樣吮旅。Web開發(fā)者可能已經(jīng)在Flutter上想要這個功能了,Get也解決了這個問題味咳。

Get.offAllNamed("/NextScreen?device=phone&id=354&name=Enzo");

在你的controller/bloc/stateful/stateless類上:

print(Get.parameters['id']);
// out: 354
print(Get.parameters['name']);
// out: Enzo

你也可以用Get輕松接收NamedParameters庇勃。

void main() {
  runApp(
    GetMaterialApp(
      initialRoute: '/',
      getPages: [
      GetPage(
        name: '/',
        page: () => MyHomePage(),
      ),
      GetPage(
        name: '/profile/',
        page: () => MyProfile(),
      ),
       //你可以為有參數(shù)的路由定義一個不同的頁面,也可以為沒有參數(shù)的路由定義一個不同的頁面槽驶,但是你必須在不接收參數(shù)的路由上使用斜杠"/"责嚷,就像上面說的那樣。
       GetPage(
        name: '/profile/:user',
        page: () => UserProfile(),
      ),
      GetPage(
        name: '/third',
        page: () => Third(),
        transition: Transition.cupertino  
      ),
     ],
    )
  );
}

發(fā)送別名路由數(shù)據(jù)

Get.toNamed("/second/34954");

在第二個頁面上掂铐,通過參數(shù)獲取數(shù)據(jù)

print(Get.parameters['user']);
// out: 34954

或像這樣發(fā)送多個參數(shù)

Get.toNamed("/profile/34954?flag=true");

在第二個屏幕上罕拂,通常按參數(shù)獲取數(shù)據(jù)

print(Get.parameters['user']);
print(Get.parameters['flag']);
// out: 34954 true

現(xiàn)在,你需要做的就是使用Get.toNamed()來導(dǎo)航你的別名路由全陨,不需要任何context(你可以直接從你的BLoC或Controller類中調(diào)用你的路由)爆班,當你的應(yīng)用程序被編譯到web時,你的路由將出現(xiàn)在URL中辱姨。

中間件

如果你想通過監(jiān)聽Get事件來觸發(fā)動作柿菩,你可以使用routingCallback來實現(xiàn)。

GetMaterialApp(
  routingCallback: (routing) {
    if(routing.current == '/second'){
      openAds();
    }
  }
)

如果你沒有使用GetMaterialApp雨涛,你可以使用手動API來附加Middleware觀察器枢舶。

void main() {
  runApp(
    MaterialApp(
      onGenerateRoute: Router.generateRoute,
      initialRoute: "/",
      navigatorKey: Get.key,
      navigatorObservers: [
        GetObserver(MiddleWare.observer), // HERE !!!
      ],
    ),
  );
}

創(chuàng)建一個MiddleWare類

class MiddleWare {
  static observer(Routing routing) {
    ///你除了可以監(jiān)聽路由外懦胞,還可以監(jiān)聽每個頁面上的SnackBars、Dialogs和Bottomsheets凉泄。
    if (routing.current == '/second' && !routing.isSnackbar) {
      Get.snackbar("Hi", "You are on second route");
    } else if (routing.current =='/third'){
      print('last route called');
    }
  }
}

現(xiàn)在躏尉,在你的代碼上使用Get:

class First extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        leading: IconButton(
          icon: Icon(Icons.add),
          onPressed: () {
            Get.snackbar("hi", "i am a modern snackbar");
          },
        ),
        title: Text('First Route'),
      ),
      body: Center(
        child: ElevatedButton(
          child: Text('Open route'),
          onPressed: () {
            Get.toNamed("/second");
          },
        ),
      ),
    );
  }
}

class Second extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        leading: IconButton(
          icon: Icon(Icons.add),
          onPressed: () {
            Get.snackbar("hi", "i am a modern snackbar");
          },
        ),
        title: Text('second Route'),
      ),
      body: Center(
        child: ElevatedButton(
          child: Text('Open route'),
          onPressed: () {
            Get.toNamed("/third");
          },
        ),
      ),
    );
  }
}

class Third extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Third Route"),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            Get.back();
          },
          child: Text('Go back!'),
        ),
      ),
    );
  }
}

免context導(dǎo)航

SnackBars

用Flutter創(chuàng)建一個簡單的SnackBar,你必須獲得Scaffold的context后众,或者你必須使用一個GlobalKey附加到你的Scaffold上胀糜。

final snackBar = SnackBar(
  content: Text('Hi!'),
  action: SnackBarAction(
    label: 'I am a old and ugly snackbar :(',
    onPressed: (){}
  ),
);
// 在小組件樹中找到腳手架并使用它顯示一個SnackBars。
Scaffold.of(context).showSnackBar(snackBar);

用Get:

Get.snackbar('Hi', 'i am a modern snackbar');

有了Get吼具,你所要做的就是在你代碼的任何地方調(diào)用你的Get.snackbar僚纷,或者按照你的意愿定制它。

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),
);


  ////////// ALL FEATURES //////////
  //     Color colorText,
  //     Duration duration,
  //     SnackPosition snackPosition,
  //     Widget titleText,
  //     Widget messageText,
  //     bool instantInit,
  //     Widget icon,
  //     bool shouldIconPulse,
  //     double maxWidth,
  //     EdgeInsets margin,
  //     EdgeInsets padding,
  //     double borderRadius,
  //     Color borderColor,
  //     double borderWidth,
  //     Color backgroundColor,
  //     Color leftBarIndicatorColor,
  //     List<BoxShadow> boxShadows,
  //     Gradient backgroundGradient,
  //     TextButton mainButton,
  //     OnTap onTap,
  //     bool isDismissible,
  //     bool showProgressIndicator,
  //     AnimationController progressIndicatorController,
  //     Color progressIndicatorBackgroundColor,
  //     Animation<Color> progressIndicatorValueColor,
  //     SnackStyle snackStyle,
  //     Curve forwardAnimationCurve,
  //     Curve reverseAnimationCurve,
  //     Duration animationDuration,
  //     double barBlur,
  //     double overlayBlur,
  //     Color overlayColor,
  //     Form userInputForm
  ///////////////////////////////////

如果您喜歡傳統(tǒng)的SnackBars拗盒,或者想從頭開始定制怖竭,包括只添加一行(Get.snackbar使用了一個強制性的標題和信息),您可以使用
Get.rawSnackbar();它提供了建立Get.snackbar的RAW API陡蝇。

Dialogs

打開Dialogs:

Get.dialog(YourDialogWidget());

打開默認Dialogs:

Get.defaultDialog(
  onConfirm: () => print("Ok"),
  middleText: "Dialog made in 3 lines of code"
);

你也可以用Get.generalDialog代替showGeneralDialog痊臭。

對于所有其他的FlutterDialogs小部件,包括cupertinos登夫,你可以使用Get.overlayContext來代替context广匙,并在你的代碼中任何地方打開它。
對于不使用Overlay的小組件恼策,你可以使用Get.context鸦致。
這兩個context在99%的情況下都可以代替你的UIcontext,除了在沒有導(dǎo)航context的情況下使用 inheritedWidget的情況涣楷。

BottomSheets

Get.bottomSheet類似于showModalBottomSheet分唾,但不需要context:

Get.bottomSheet(
  Container(
    child: Wrap(
      children: <Widget>[
        ListTile(
          leading: Icon(Icons.music_note),
          title: Text('Music'),
          onTap: () {}
        ),
        ListTile(
          leading: Icon(Icons.videocam),
          title: Text('Video'),
          onTap: () {},
        ),
      ],
    ),
  )
);

嵌套導(dǎo)航

Get讓Flutter的嵌套導(dǎo)航更加簡單。
你不需要context狮斗,而是通過Id找到你的導(dǎo)航棧绽乔。

  • 注意:創(chuàng)建平行導(dǎo)航堆棧可能是危險的碳褒。理想的情況是不要使用NestedNavigators折砸,或者盡量少用。如果你的項目需要它沙峻,請繼續(xù)睦授,但請記住,在內(nèi)存中保持多個導(dǎo)航堆椬ㄐ铮可能不是一個好主意(消耗RAM)睹逃。

看看它有多簡單:

Navigator(
  key: Get.nestedKey(1), // create a key by index
  initialRoute: '/',
  onGenerateRoute: (settings) {
    if (settings.name == '/') {
      return GetPageRoute(
        page: () => Scaffold(
          appBar: AppBar(
            title: Text("Main"),
          ),
          body: Center(
            child: TextButton(
              color: Colors.blue,
              onPressed: () {
                Get.toNamed('/second', id:1); // navigate by your nested route by index
              },
              child: Text("Go to second"),
            ),
          ),
        ),
      );
    } else if (settings.name == '/second') {
      return GetPageRoute(
        page: () => Center(
          child: Scaffold(
            appBar: AppBar(
              title: Text("Main"),
            ),
            body: Center(
              child:  Text("second")
            ),
          ),
        ),
      );
    }
  }
),
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子沉填,更是在濱河造成了極大的恐慌疗隶,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件翼闹,死亡現(xiàn)場離奇詭異斑鼻,居然都是意外死亡,警方通過查閱死者的電腦和手機猎荠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門坚弱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人关摇,你說我怎么就攤上這事荒叶。” “怎么了输虱?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵些楣,是天一觀的道長。 經(jīng)常有香客問我宪睹,道長愁茁,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任亭病,我火速辦了婚禮鹅很,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘罪帖。我一直安慰自己促煮,他們只是感情好,可當我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布整袁。 她就那樣靜靜地躺著污茵,像睡著了一般。 火紅的嫁衣襯著肌膚如雪葬项。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天迹蛤,我揣著相機與錄音民珍,去河邊找鬼。 笑死盗飒,一個胖子當著我的面吹牛嚷量,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播逆趣,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼蝶溶,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起抖所,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤梨州,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后田轧,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體暴匠,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年傻粘,在試婚紗的時候發(fā)現(xiàn)自己被綠了每窖。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡弦悉,死狀恐怖窒典,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情稽莉,我是刑警寧澤瀑志,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站肩祥,受9級特大地震影響后室,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜混狠,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一岸霹、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧将饺,春花似錦贡避、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至掖蛤,卻和暖如春杀捻,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蚓庭。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工致讥, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人器赞。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓垢袱,卻偏偏與公主長得像,于是被迫代替她去往敵國和親港柜。 傳聞我的和親對象是個殘疾皇子请契,可洞房花燭夜當晚...
    茶點故事閱讀 44,979評論 2 355