美文网首页FlutterFlutter
flutter get 插件介绍

flutter get 插件介绍

作者: 天空蓝雨 | 来源:发表于2022-09-24 11:18 被阅读0次

    get 插件官方文档
    get gitbook
    get 插件里面有很多有用的功能,大概有下面几个:

    snackbar 消息通知的弹框

    dialog 对话框

    bootomsheet

    navigation 导航路由
    obx 响应式状态管理(类似 vue, 不用写 setState 了)

    通过 get cli 来创建项目
    https://github.com/jonataslaw/get_cli

    get cli 文档

    get cli

    安装:

    pub global activate get_cli 
    

    get cli 创建项目

    get  create  project:xxx
    会同时执行新建项目和 get  init
    如果上面的 卡住,用下面的代替
    
    flutter create project_name
    cd project_name
    get init
    

    get 快速开始

    编辑:pubspec.yaml

    dependencies:
      get: ^4.1.1
    

    状态管理

    简单的状态管理器(GetBuilder)和响应式状态管理器(GetX)

    官方计时器例子

    • 变量控制器controller (继承 GetxController)
    class Controller extends GetxController{
      var count = 0.obs;
      increment() => count++;
    }
    
    • 页面
      使用Getx你可能不再需要使用StatefulWidget, 直接 StatelessWidget 可以节省内存
    // 第一个页面
    class Home extends StatelessWidget {
    
      @override
      Widget build(context) {
    
        // 使用Get.put()实例化你的类,使其对当下的所有子路由可用。
        final Controller c = Get.put(Controller());
    
        return Scaffold(
          // 使用Obx(()=>每当改变计数时,就更新Text()。
          appBar: AppBar(title: Obx(() => Text("Clicks: ${c.count}"))),
    
          // 用一个简单的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));
      }
    }
    
    // 第二个页面
    class Other extends StatelessWidget {
      // 你可以让Get找到一个正在被其他页面使用的Controller,并将它返回给你。
      final Controller c = Get.find();
    
      @override
      Widget build(context){
         // 访问更新后的计数变量
         return Scaffold(body: Center(child: Text("${c.count}")));
      }
    }
    

    定义响应式变量

    Controller 类里面定义变量的时候,如果声明一个可响应式的变量有下面几种方式

    • 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, 更新里面的属性需要 显式 调用 refresh 或者 update 方法:

    final user = User(name: 'John', last: 'Doe', age: 33).obs;
    
    // `user`是 "响应式 "的,但里面的属性却不是!
    // 所以,如果我们改变其中的一些变量:
    user.value.name = 'Roi';
    // 小部件不会重建! 
    // 对于自定义类,我们需要手动 "通知 "改变。
    user.refresh();
    
    // 或者我们可以使用`update()`方法!
    user.update((value){
      value.name='Roi';
    });
    
    

    路由导航

    普通导航

    • 导航到新页面
    Get.to(NextScreen());
    
    • 关闭页面
      SnackBars、Dialogs、BottomSheets, 和任何可以 Navigator.pop(context) 关闭的东西
    Get.back();
    
    • 新页面,没有返回按钮 (登录页面, 欢迎页面等 不准用户返回上个页面的)
    Get.off(NextScreen());
    
    • 进入下一个界面并取消之前的所有路由
      在购物车、投票和测试中很有用 ?
      Get.offAll(NextScreen());

    • 导航到下一条路由,并在返回后立即接收数据

    // Payment
    Get.back(result: 'success');
    var data = await Get.to(Payment());
    // data    result: 'success'
    

    和 原生打开页面对比

    // 默认的Flutter导航
    Navigator.of(context).push(
      context,
      MaterialPageRoute(
        builder: (BuildContext context) {
          return HomePage();
        },
      ),
    );
    // get 的导航
    Get.to(HomePage());
    

    别名导航

    普通导航后面加 Named 就可以啦
    需要在 GetMaterialApp 定义 getPages 路由列表(其实和 MaterialApp 定义的路由差不多)

    void main() {
      runApp(
        GetMaterialApp(
          initialRoute: '/',
          getPages: [
            GetPage(name: '/', page: () => MyHomePage()),
            GetPage(name: '/second', page: () => Second()),
            GetPage(
              name: '/third',
              page: () => Third(),
              transition: Transition.zoom  
            ),
          ],
        )
      );
    
    • 导航到下一个页面
    Get.toNamed("/NextScreen");
    
    • 打开并删除前一个页面
    Get.offNamed("/NextScreen");
    
    • 浏览并删除之前所有的页面
    Get.offAllNamed("/NextScreen");
    

    路由传参

    • 直接是查询参数:
    Get.offAllNamed("/NextScreen?device=phone&id=354&name=Enzo");
    
    

    另一个页面获取参数:

    print(Get.parameters['id']);
    // out: 354
    print(Get.parameters['name']);
    // out: Enzo
    
    • 传递 uri 参数
      (uri 里面 用 : 分割 , 类似 gin 里面uri 里面的)
      如果有两个 比如 /profile//profile/:user 短的profile 必须 用 / 结尾
    GetPage(
            name: '/profile/',
            page: () => MyProfile(),
          ),
           //你可以为有参数的路由定义一个不同的页面,也可以为
    没有参数的路由定义一个不同的页面,但是你必须在不接收参数的路由上使用斜杠"/",就像上面说的那样。
           GetPage(
            name: '/profile/:user',
            page: () => UserProfile(),
          ),
    

    上面路由可以下面传参和获取

    Get.toNamed("/profile/34954?flag=true");
    print(Get.parameters['user']);
    print(Get.parameters['flag']);
    // out: 34954 true
    

    中间件

    中间件通过监听Get事件来触发动作,你可以使用routingCallback来实现

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

    一些弹框

    • 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),
    );
    
    final snackBar = SnackBar(
      content: Text('Hi!'),
      action: SnackBarAction(
        label: 'I am a old and ugly snackbar :(',
        onPressed: (){}
      ),
    );
    
    // 在小组件树中找到脚手架并使用它显示一个SnackBars。
    Scaffold.of(context).showSnackBar(snackBar);
    

    上面等价于

    Get.snackbar('Hi', 'i am a modern snackbar');
    
    • Dialogs
    Get.dialog(YourDialogWidget());
    
    • BottomSheets

    GetView

    如果只依赖一个控制器 GetView 会简化开发,如果多个还是按照原来的写法吧。
    可以直接写这样,然后就会有一个 默认的 controller 控制器实例可以用了
    Get.put(Controller());
    直接 继承 GetView<AwesomeController> (要把 自己定义的 controller 写到模板类型里)
    里面直接使用 controller 代指 controller 实例

    class AwesomeController extends GetxController {
       final String title = 'My Awesome View';
     }
    
      // 一定要记住传递你用来注册控制器的`Type`!
     class AwesomeView extends GetView<AwesomeController> {
       @override
       Widget build(BuildContext context) {
         return Container(
           padding: EdgeInsets.all(20),
           child: Text( controller.title ), // 只需调用 "controller.something"。
         );
       }
     }
    

    Bindings

    Bindings 主要是配合路由进行使用,当通过 GetX 路由进入页面时,会自动调用 dependencies 方法。 可以方便的帮我们做一些 接口 请求初始化的操作, 然后在 controller 里面就非常方便的使用 请求了。重点是 代码结构清晰。

    Page 中就能正常使用 Get.find ( GetView 的可以直接 controller 也可以 find )获取到注入的 Controller 对象
    就不用写 get.put() 了
    binding 多个 Controller ,可以依次通过 find 获取实例

    final HomeController1 c = Get.find();
    final HomeController c = Get.find();
    或者
    Get.find<HomeController1 >().
    

    可以看到只要传指定的类型,find 就可以获对应的 实例

    关于 get cli 进阶使用

    https://1467602180.github.io/flutter-getx-doc/engineer/advanced#%E4%BD%BF%E7%94%A8

    遇到的问题

    就是我需要修改某个 obs 属性,一开始没有 用 Obx 来包装,导致样式不对,后来用Obx 包装一下就好了。就是说,如果一个组件和 obs 属性关联,那要用 Obx 包装才能起到响应式改变

    Scaffold(
    //bottomNavigationBar 虽然没用到 controller.select_index ,但是要重新渲染就要用 Obx 修改, 因为bottomNavigationBar  用到了 currentIndex, 也就是Obx 的属性。
          bottomNavigationBar: Obx(() => BottomNavigationBar(
            items: <BottomNavigationBarItem>[
              BottomNavigationBarItem(icon: Icon(Icons.home), label: '首页'),
              BottomNavigationBarItem(icon: Icon(Icons.business), label: '发现'),
              BottomNavigationBarItem(icon: Icon(Icons.school), label: '个人中心'),
            ],
            currentIndex:  controller.select_index.value,
            selectedItemColor: Colors.teal,
            onTap: (int index){ controller.select_index.value = index; },
          )),
          body: Obx(() => tab_widget[controller.select_index.value])
        );
    

    响应式属性:

    设置属性和获取属性,如果是响应式的都要 .value 不然可能不会做到响应和属性绑定。

    相关文章

      网友评论

        本文标题:flutter get 插件介绍

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