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

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

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

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

class GetTestPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    print('SimplePage--build');
    CountController initController = Get.put(CountController()); //初始化
       return GetBuilder(
        //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().counter.toString(),
            style: TextStyle(fontSize: 30),
          ),
          FloatingActionButton(
            heroTag: "get_test1_increment",
            onPressed: () {
              controller.increment();
              // initController.increment();
              // Get.find().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(
            // 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().increment();
                },
                child: Text(
                  '点击+1-----${Get.find().counter}',
                  style: TextStyle(
                      fontWeight: FontWeight.bold, color: Colors.white),
                ),
              )),
          TextButton(
            style: ButtonStyle(
                backgroundColor: MaterialStateProperty.all(Colors.blue)),
            onPressed: () {
              Get.find().increment();
            },
            child: Text(
              '无法观察变化 +1 -----${Get.find().counter}',
              style:
                  TextStyle(fontWeight: FontWeight.bold, color: Colors.white),
            ),
          )
        ]),
      ),
    );
  }
}

使用Obx观察数据

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

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

  • (1)获取数据改变数据既然可以直接使用Get.find()拿到controller,就能改变数据,展示数据,为什么还要使用上述的3种方法?
    通过上面例子中的最后一个 "无法观察变化 +1"此按钮可以看出,直接使用Get.find()拿到的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()时,也是这样的调用流程,获取到的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 {
  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(
// 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的使用)