美文网首页Flutterflutter
flutter-状态管理4-get的使用

flutter-状态管理4-get的使用

作者: 浮华_du | 来源:发表于2021-04-02 17:54 被阅读0次

    一、首先,依然是计数器的

    1.构建共享数据

    • update()
      使用GetBuilder 获取共享数据,并操作变化时,需要执行update()才能被通知到GetBuilder.
    • .obs
      给数据源加了.obs意味着 将其变成了rx响应数据(此例子中即RxInt),可以直接使用Obx语法监听,并操作变化.无需调用update()方法
    
    class CountController extends GetxController {
      var _counter = 0.obs;
      get counter => _counter;
    
      void increment() {
        _counter++;
        update();
      }
    
      @override
      void onInit() {
        super.onInit();
        print('CountController--onInit');
      }
    
      @override
      void onReady() {
        super.onReady();
        print('CountController--onReady');
      }
    
      @override
      void onClose() {
        super.onClose();
        print('CountController--onClose');
      }
    }
    

    2.获取controller, 操作数据

    使用GetBuilder获取controller

    1.需要在使用前 或 init参数中初始化共享数据Controller

    (1) 使用前初始化的方式:CountController initController = Get.put(CountController());

    (2) GetBuilder 的init参数初始化方式:

    GetBuilder<CountController>(
           init: CountController(), //这里不初始化 , 就在上面初始化
           tag: "init_tag", //这里init不初始化,也不要设置这个tag; 设置了tag 数据就不是共享的了
            builder: ...
    )
    
    • 2.获取数据改变数据的方式:

    (1)可以使用build内返回的controller来获取数据和改变数据;
    (2)可以用初始化initController获取数据和改变数据
    (3)可以用Get.find<CountController>()可以用来获取数据和改变数据

    class GetTestPage extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        print('SimplePage--build');
        CountController initController = Get.put(CountController()); //初始化
           return GetBuilder<CountController>(
            //GetBuilder不监听obs更改,更改必须通过调用controller.update()
            // init: CountController(), //这里不初始化 , 就在上面初始化
            // tag: "init_tag", //这里init不初始化,也不要设置这个tag; 设置了tag 数据就不是共享的了
            builder: (controller) {
          print("GetBuilder--refresh");
          return Scaffold(
            appBar: AppBar(title: Text('Get')),
            body: Center(
                child: Column(children: [
              Text(
                controller.counter.toString(),
                style: TextStyle(fontSize: 30),
              ),
              Text(
                initController.counter.toString(),
                style: TextStyle(fontSize: 30),
              ),
              Text(
                Get.find<CountController>().counter.toString(),
                style: TextStyle(fontSize: 30),
              ),
              FloatingActionButton(
                heroTag: "get_test1_increment",
                onPressed: () {
                  controller.increment();
                  // initController.increment();
                  // Get.find<CountController>().increment();
                },
                child: Icon(Icons.add),
              ),
               ])),
            floatingActionButton: FloatingActionButton(
              heroTag: "get_totest2",
              onPressed: () {
                Navigator.push(context, MaterialPageRoute(builder: (context) {
                  return GetTest2Page();
                }));
              },
              child: Icon(Icons.next_plan),
            ),
          );
        });
      }
    }
    

    使用GetX获取controller

    • 使用及注意事项与GetBuilder相同(需要初始化controller;改变数据及获取数据的方式)
    class GetTest2Page extends StatelessWidget {
      const GetTest2Page({Key key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        CountController initController = Get.put(CountController()); //Obx需要初始化
        print('SimplePage2--build');
        return Scaffold(
          appBar: AppBar(title: Text('Get')),
          body: Center(
            child: Column(children: [
              GetX<CountController>(
                // init: CountController(),//默认在这里初始化,不初始化的话,将会使用上边初始化的Controller
                builder: (controller) {
                  print('GetX--refresh');
                  return TextButton(
                    style: ButtonStyle(
                        backgroundColor: MaterialStateProperty.all(Colors.blue)),
                    onPressed: () {
                      controller.increment();
                    },
                    child: Text(
                      '点击+1-----${controller.counter}',
                      style: TextStyle(
                          fontWeight: FontWeight.bold, color: Colors.white),
                    ),
                  );
                },
              ),
              Obx(() => TextButton(
                    style: ButtonStyle(
                        backgroundColor: MaterialStateProperty.all(Colors.blue)),
                    onPressed: () {
                      initController.increment();
                    },
                    child: Text(
                      '点击+1-----${initController.counter}',
                      style: TextStyle(
                          fontWeight: FontWeight.bold, color: Colors.white),
                    ),
                  )),
              Obx(() => Text(
                '仅显示===${initController.counter}',
                style: TextStyle(
                    fontWeight: FontWeight.bold, color: Colors.black),
              )),
              Obx(() => TextButton(
                    style: ButtonStyle(
                        backgroundColor: MaterialStateProperty.all(Colors.blue)),
                    onPressed: () {
                      Get.find<CountController>().increment();
                    },
                    child: Text(
                      '点击+1-----${Get.find<CountController>().counter}',
                      style: TextStyle(
                          fontWeight: FontWeight.bold, color: Colors.white),
                    ),
                  )),
              TextButton(
                style: ButtonStyle(
                    backgroundColor: MaterialStateProperty.all(Colors.blue)),
                onPressed: () {
                  Get.find<CountController>().increment();
                },
                child: Text(
                  '无法观察变化 +1 -----${Get.find<CountController>().counter}',
                  style:
                      TextStyle(fontWeight: FontWeight.bold, color: Colors.white),
                ),
              )
            ]),
          ),
        );
      }
    }
    
    

    使用Obx观察数据

    • (1)数据源一定是Rx...(后面加.obs); 更新方法无需使用update()
    • (2)使用前一定要初始化controller
    • (3)Obx(() =>widget) widget内可以展示数据,改变数据

    二、Get.find<CountController>()的内部实现

    • (1)获取数据改变数据既然可以直接使用Get.find<CountController>()拿到controller,就能改变数据,展示数据,为什么还要使用上述的3种方法?
      通过上面例子中的最后一个 "无法观察变化 +1"此按钮可以看出,直接使用Get.find<CountController>()拿到的controller,可以改变数据,但是这个按钮本身并不具备观察功能,改变数据时,这个值并不会刷新.
    • (2)通过源码可以看出,在初始化controller时,Get.put内部会先走_insert方法,然后走find方法,返回一个controller.
      CountController initController = Get.put(CountController());
      image.png
      _insert方法 内部,会根据这个controller的tag或名字, 生成一个唯一key,并加入到_singl内.
      image.png
      find方法 会先从_initDependencies内部寻找是否有对应tag的controller可以返回(是否初始化,没有的话先初始化);有的话,直接返回,没有的话,通过key在_singl中拿到.
      image.png
      image.png
      所以,当我们使用Get.find<CountController>()时,也是这样的调用流程,获取到的controller.这个controller与其他方式获取到的controller是同一个controller.

    三、实际使用,渲染一个列表-- obx方式

    • 1.共享数据
    import 'package:get/get.dart';
    
    class TestGetLogic extends GetxController {
    
      RxList _list = [].obs;
      get list => _list;
    
      addListData(List data){
        _list.addAll(data);
        // update();
      }
    
    }
    
    • 2.使用页面
    class TestGetPage extends StatefulWidget {
      @override
      _TestGetPageState createState() => _TestGetPageState();
    }
    
    class _TestGetPageState extends State<TestGetPage> {
      TestGetLogic logic;
    
      _TestGetPageState() {
        logic = Get.put(TestGetLogic());
      }
    
      @override
      void initState() {
        ///模拟网络请求,拿到数据
       Future.delayed(Duration(milliseconds: 360), () {
        logic.addListData(["达拉崩吧", "崩德比迪")]);
        });
        super.initState();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            appBar: AppBar(),
            body: Column(
              children: [
                Obx(() { //Obx配合.obs 数据刷新
                  return Text("${logic.list.length}");
                }),
                Obx(() {
                  return Expanded(
                    child: ListView.builder(
                        itemCount: logic.list.length,
                        itemBuilder: (context, index) {
                          return _listItem(logic.list[index]);
                        }),
                  );
                }),
              ],
            ),
        );
    
    //     body: GetBuilder<TestGetLogic>(
    // builder: (controller) { //刷新需要配合update()
    //   return ListView.builder(
    //       itemCount: logic.list.length,
    //     itemBuilder: (context, index) {
    //       return _listItem("${logic.list[index]}");
    //     });
    // }));
      }
    
      Widget _listItem(String str) {
        return Padding(
          padding: const EdgeInsets.all(15.0),
          child: Container(
            padding: const EdgeInsets.all(5.0),
            color: Colors.black12,
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  str,
                  maxLines:1,
                  style: TextStyle(fontSize: 18,fontWeight: FontWeight.w500),
                ),
              ],
            ),
          ),
        );
      }
    }
    
    

    问题

    本例仅实现了向list里面增加数据, 那如何清空数据,修改数据呢 ?(以下示例无法实现)
    refreshListData(List data){
    _list = data.obs;
    }
    removeAll(){
    _list = [].obs;
    }

    欢迎点点小心心哦~

    相关文章

      网友评论

        本文标题:flutter-状态管理4-get的使用

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