美文网首页
Flutter Getx 入门

Flutter Getx 入门

作者: 我叫Aliya但是被占用了 | 来源:发表于2023-12-13 13:21 被阅读0次

    提供了状态管理、智能依赖注入、和路由能力。

    状态管理

    class Controller extends GetxController{
      var count = 0.obs;      // 响应式
      increment() => count++; // 不再需要 setState
    }
    
    class Home extends StatelessWidget {
      final Controller c = Get.put(Controller(), 'my-counter');  // 创建实例
      // final Controller c = Get.find(tag: 'my-counter'); // 查找并使用一个已存在的Controller
      // final Controller c = Get.find<Controller>(); // 同上
    
      @override
      Widget build(context){
        Obx(() => Text("${c.count.value}")); // 当count变化后重绘此处
        GetBuilder<Controller>(        // 复杂数据类型使用GetBuilder提高性能
          init: Controller(), // 首次启动
          builder: (_) => Text("${c.count.value}"),
        )
      }
    }
    // or
    class Home extends GetView<Controller> {
      @override
      Widget build(context){ ... } // 直接可用 controller 属性
    

    创建响应式的 3 种方法:

    • final name = RxString('')
    • final name = Rx<String>('')
    • final name = ''.obs
      • 基础类型在使用时需要name.value,复杂类型可以直接使用(类需要自己实现)

    watch:

    • ever(count1, (_) => print("count1 has been changed to $_"));

      • dart immediate 默认为 true, count1.firstRebuild = false 取消 immediate
    • 只监听一次使用once方法

    • 自带防抖和节流

      • debounce(count1, (_) => ..., time: Duration(seconds: 1))
      • interval(count1, (_) => ..., time: Duration(seconds: 1))

    GetBuilder: rerender 时机 - 它为了性能主动放弃了响应式,rerender 时机、范围都由开发者控制以达到性能最大化(大大减少了事件监听发送、内存占用)

    • 不再依赖StatefulWidget的状态管理,所有状态放入GetxController,组件全部StatelessWidget

    • initStatedispose,效果同StatefulWidget(不推荐)

    • 有生命周期onInitonReadyonClose(推荐)

      class Controller extends GetxController {
        int counter = 0;
        void increment() {
          counter++;
          update(); // 主动rerender
        }
      }
      
      GetBuilder<Controller>(
        init: Controller(),   // 首次启动自动初始化,组件卸载时自动删除
        builder: (_) => Text( // rerender只会重绘builder方法
          '${_.counter}',
        ),
      )
      
    • “如需要使用的控制器已在内存中,将与内存中的共享” 初始化 2 次但只有一个实例吗?

    路由

    GetMaterialApp( // Before: MaterialApp(
      home: MyHome(),
      initialRoute:"/", // same as before
      //routes:{
      //  "new_page":(context) => NewRoute(),
      //  "/":(context) => MyHomePage(title: '首页'),
      //},
      getPages: [
        GetPage(name: '/', page: () => MyHomePage()),
        GetPage(name: '/new_page', page: () => Second()),
      ],
    )
    
    // Navigator.push
    Get.to(NextScreen());
    // Navigator.pushNamed
    Get.toNamed('/details', arguments: '12');
    print(Get.arguments); // 12
    // Navigator.pop
    Get.back(result: '参数');
    var data = await Get.to(Xxx()); // 参数
    // replace
    Get.off(NextScreen());
    // reLaunch
    Get.offAll(NextScreen());
    
    // 类URL传参
    Get.toNamed('/details?id=12');
    print(Get.parameters['id']); // 12
    // or
    GetPage(name: '/details/:id', page: () => Second())
    Get.toNamed("/details/12");
    print(Get.parameters['id']); // 12
    

    路由守卫

    MaterialApp(
      ...
      // before
      // onGenerateRoute:(RouteSettings settings) {
      //    return MaterialPageRoute(builder: (context){
      //      String routeName = settings.name;
      //      // 如果访问的路由页需要登录,但当前未登录,则直接返回登录页路由。
      //    }
      //  );
      // }
      routingCallback: (routing) {
        if(routing.current == '/second'){
          // do something
        }
      }
    );
    

    基于中间件的路由守卫

    MaterialApp(
      onGenerateRoute: Router.generateRoute,
      initialRoute: "/",
      navigatorKey: Get.key,
      navigatorObservers: [
        GetObserver(MiddleWare.observer), // HERE !!!
      ],
    )
    
    class MiddleWare {
      static observer(Routing routing) {
        if(routing.current == '/second'){
          // do something
        }
      }
    }
    

    它还有 国际化、主题、请求 等能力

    // 无需 context 使用 snackbar
    Get.snackbar('Hi', 'i am a modern snackbar');
    // 和 Dialogs
    Get.defaultDialog(
      onConfirm: () => print("Ok"),
      middleText: "Dialog made in 3 lines of code"
    );
    // bottomSheet
    Get.bottomSheet(
      Container(
        child: Wrap(
          children: [
            ListTile(
              leading: Icon(Icons.music_note),
              title: Text('Music'),
              onTap: () {}
            ),
            ListTile(
              leading: Icon(Icons.videocam),
              title: Text('Video'),
              onTap: () {},
            ),
          ],
        ),
      )
    );
    

    状态管理 https://github.com/jonataslaw/getx/blob/4.6.1/documentation/zh_CN/state_management.md

    依赖管理 https://github.com/jonataslaw/getx/blob/4.6.1/documentation/zh_CN/dependency_management.md

    路由管理 https://github.com/jonataslaw/getx/blob/4.6.1/documentation/zh_CN/route_management.md

    https://pub-web.flutter-io.cn/packages/get

    https://github.com/jonataslaw/getx

    相关文章

      网友评论

          本文标题:Flutter Getx 入门

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