GetX 路由管理

作者: KB_MORE | 来源:发表于2021-05-28 16:50 被阅读0次

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

    路由管理

    这是关于Getx在路由管理方面的完整解释。

    如何使用

    将此添加到你的pubspec.yaml文件中。

    dependencies:
      get:
    

    如果你要在没有context的情况下使用路由/SnackBars/Dialogs/BottomSheets,或者使用高级的Get API,你只需要在你的MaterialApp前面加上 "Get",就可以把它变成GetMaterialApp,享受吧!

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

    普通路由导航

    导航到新的页面。

    Get.to(NextScreen());
    

    关闭SnackBars、Dialogs、BottomSheets或任何你通常会用Navigator.pop(context)关闭的东西。

    Get.back();
    

    进入下一个页面,但没有返回上一个页面的选项(用于SplashScreens,登录页面等)。

    Get.off(NextScreen());
    

    进入下一个界面并取消之前的所有路由(在购物车、投票和测试中很有用)。

    Get.offAll(NextScreen());
    

    要导航到下一条路由,并在返回后立即接收或更新数据。

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

    在另一个页面上,发送前一个路由的数据。

    Get.back(result: 'success');
    

    并使用它,例:

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

    你不想学习我们的语法吗?
    只要把 Navigator(大写)改成 navigator(小写),你就可以拥有标准导航的所有功能,而不需要使用context,例如:

    
    // 默认的Flutter导航
    Navigator.of(context).push(
      context,
      MaterialPageRoute(
        builder: (BuildContext context) {
          return HomePage();
        },
      ),
    );
    
    // 使用Flutter语法获得,而不需要context。
    navigator.push(
      MaterialPageRoute(
        builder: (_) {
          return HomePage();
        },
      ),
    );
    
    // get语法 (这要好得多)
    Get.to(HomePage());
    
    
    

    别名路由导航

    • 如果你喜欢用别名路由导航,Get也支持。

    导航到下一个页面

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

    要处理到未定义路线的导航(404错误),可以在GetMaterialApp中定义unknownRoute页面。

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

    发送数据到别名路由

    只要发送你想要的参数即可。Get在这里接受任何东西,无论是一个字符串,一个Map,一个List,甚至一个类的实例。

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

    在你的类或控制器上:

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

    动态网页链接

    Get提供高级动态URL,就像在Web上一样。Web开发者可能已经在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(),
          ),
           //你可以为有参数的路由定义一个不同的页面,也可以为没有参数的路由定义一个不同的页面,但是你必须在不接收参数的路由上使用斜杠"/",就像上面说的那样。
           GetPage(
            name: '/profile/:user',
            page: () => UserProfile(),
          ),
          GetPage(
            name: '/third',
            page: () => Third(),
            transition: Transition.cupertino  
          ),
         ],
        )
      );
    }
    

    发送别名路由数据

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

    在第二个页面上,通过参数获取数据

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

    或像这样发送多个参数

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

    在第二个屏幕上,通常按参数获取数据

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

    现在,你需要做的就是使用Get.toNamed()来导航你的别名路由,不需要任何context(你可以直接从你的BLoC或Controller类中调用你的路由),当你的应用程序被编译到web时,你的路由将出现在URL中。

    中间件

    如果你想通过监听Get事件来触发动作,你可以使用routingCallback来实现。

    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 !!!
          ],
        ),
      );
    }
    

    创建一个MiddleWare类

    class MiddleWare {
      static observer(Routing routing) {
        ///你除了可以监听路由外,还可以监听每个页面上的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');
        }
      }
    }
    

    现在,在你的代码上使用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导航

    SnackBars

    用Flutter创建一个简单的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,你所要做的就是在你代码的任何地方调用你的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
      ///////////////////////////////////
    

    如果您喜欢传统的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,除了在没有导航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: () {},
            ),
          ],
        ),
      )
    );
    

    嵌套导航

    Get让Flutter的嵌套导航更加简单。
    你不需要context,而是通过Id找到你的导航栈。

    • 注意:创建平行导航堆栈可能是危险的。理想的情况是不要使用NestedNavigators,或者尽量少用。如果你的项目需要它,请继续,但请记住,在内存中保持多个导航堆栈可能不是一个好主意(消耗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")
                ),
              ),
            ),
          );
        }
      }
    ),
    

    相关文章

      网友评论

        本文标题:GetX 路由管理

        本文链接:https://www.haomeiwen.com/subject/twissltx.html