[Flutter] Getx学习日记


Flutter Getx

1:模块介绍

states状态层

state只专注数据,需要使用数据,直接通过state获取。

定义变量只在state,定义可监听字符串alice。

import 'package:get/get.dart';
class HomeState{
  ///定义可监听变量
  RxString msg='alice'.obs;
}

logic层(controllers)

logic只专注于触发事件交互,操作或更新数据。

定义方法,数据变化,初始化数据,操作数据在controller

import 'package:get/get.dart';
import 'package:getx_demo/app/modules/home/states/home_state.dart';
class HomeController extends GetxController {
    //连接state,可以操作state里的变量
  HomeState state =HomeState();
    //自定义方法,改变state里的msg变量的值
  ChangeMsg(){
      //Rx类型要加.value才能被基础类型数据赋值
    state.msg.value='jett';
  }
    
 ///初始化数据,从别人传过来的数据不打算更新的写在这里
  @override
  void onInit() {
    super.onInit();
  }
    
///加载完成,从别人传过来的数据打算更新的写在这里
    ///需要再刷新一次才能正常显示数据
  @override
  void onReady() {
    super.onReady();
  }
    
   ///控制器被释放
  @override
  void onClose() {}
}

bindings依赖注入

import 'package:get/get.dart';
import '../controllers/home_controller.dart';
class HomeBinding extends Bindings {
  @override
  void dependencies() {
    ///懒加载控制器,只有控制器被调用才会初始化
    Get.lazyPut(
      () => HomeController(),
    );
  }
}

views显示层

view只专注UI显示

import 'package:get/get.dart';
import '../controllers/home_controller.dart';
class HomeView extends GetView {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('HomeView'),
          centerTitle: true,
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
                ///用Obx包裹有可监听变量的widget
                ///变量改变是会刷新
              Obx(() {
                return Text(controller.state.msg.value);
              }),
              ElevatedButton(onPressed: (){
                controller.ChangeMsg();
              }, child: Text('Change'))
            ],
          ),
        )
    );
  }
}

2:路由传值

路由传值示例demo
新加一个second页面

home页面

controllers
///新添加一个命名路由里跳转方法
toSecond(){
    //arguments的值是传的参数
    Get.toNamed(Routes.SECOND,arguments: state.msg.value);
}
views
///新加了一个按钮,包含了toSecond跳转事件
ElevatedButton(onPressed: (){
    controller.toSecond();
}, child: Text('go to second page'))

second页面

states
///新声明一个变量来存储home页面传过来的值
import 'package:get/get.dart';
class SecondState{
  RxString msgFromHome=''.obs;
}
controllers
  SecondState state =SecondState();
  @override
  void onInit() {
    super.onInit();
      ///Get.arguments:路由跳转过来的值,将其存到msgFromHome
    state.msgFromHome.value=Get.arguments;
  }
views
///显示存储传过来的值的变量msgFromHome,记得加.value
body: Center(
    child: Obx(() {
        return Text(
            controller.state.msgFromHome.value,
            style: TextStyle(fontSize: 20),
        );
    }),
),

3:路由返回带参数

home页面

states
import 'package:get/get.dart';
class HomeState{
  ///定义监听变量
  RxString msg='alice'.obs;
    ///新增一个变量来存储从second返回过来的值,因为
  RxString msgFromSecond='value from second'.obs;
}
controllers
///修改toSecond,返回时接收返回参数
toSecond()async{
    ///result的类型等于返回时带的参数的类型
    var result= await Get.toNamed(Routes.SECOND,arguments: state.msg.value);
    ///将返回的值赋值给msgFromSecond
    state.msgFromSecond.value=result;
}
views
///新增一个Text显示从second页面返回来的值
Obx(() {
    return Text(controller.state.msgFromSecond.value);
}),

second页面

controllers
///新加一个返回的方法,将字符串返回
getBack(){
    Get.back(result: 'hello , im from second');
}
views
leading: IconButton(
    onPressed: (){
        ///调用返回方法
        controller.getBack();
    },
    icon: Icon(Icons.arrow_back),
),

4:列表传值

列表传值示例demo
api: https://jdmall.itying.com/api/pcate

生成model

通过json to dart生成model,注意这个接口的status变量有问题,在model里删掉,以免报错。

class GoodsModel {
  List? result;

  GoodsModel({this.result});

  GoodsModel.fromJson(Map json) {
    if (json['result'] != null) {
      result = [];
      json['result'].forEach((v) {
        result!.add(new Result.fromJson(v));
      });
    }
  }

  Map toJson() {
    final Map data = new Map();
    if (this.result != null) {
      data['result'] = this.result!.map((v) => v.toJson()).toList();
    }
    return data;
  }
}

class Result {
  String? sId;
  String? title;
  String? pic;
  String? pid;
  String? sort;

  Result({this.sId, this.title, this.pic, this.pid, this.sort});

  Result.fromJson(Map json) {
    sId = json['_id'];
    title = json['title'];
    pic = json['pic'];
    pid = json['pid'];
    sort = json['sort'];
  }

  Map toJson() {
    final Map data = new Map();
    data['_id'] = this.sId;
    data['title'] = this.title;
    data['pic'] = this.pic;
    data['pid'] = this.pid;
    data['sort'] = this.sort;
    return data;
  }
}

home页面

states
import 'package:get/get.dart';
import 'package:getx_demo/app/data/GoodsModel.dart';
class HomeState{
    ///定义一个List来存储Result实例
  RxList goodsData=[].obs;
}
controllers
///定义一个方法,获取接口的数据
getData()async{
    final response= await Dio().get('https://jdmall.itying.com/api/pcate');
    final goodsList = GoodsModel.fromJson(response.data);
    ///goodsList.result的类型是List,将其存入state.goodsData
    state.goodsData.value=goodsList.result!;
  }
///跳转到第二个页面,把List通过index把单个Result实例传到第二个页面
  toDetail(int index){
    Get.toNamed(Routes.SECOND,arguments: state.goodsData[index]);
  }

  @override
  void onInit() {
    super.onInit();
      ///初始化获取数据的方法
    getData();
  }
views
///在ListView外面包裹Obx,这样加载数据可以build一下把数据显示出来
Obx(() {
    return ListView.builder(
        itemCount: controller.state.goodsData.length,
        itemBuilder: (context, index) {
            return InkWell(
                onTap: () {
                    ///执行toDetail方法,把Result实例传到第二个页面
                    controller.toDetail(index);
                },
                child: ListTile(
                    title: Text(controller.state.goodsData[index].title ??
                                '')
                ),
            );
        });
})

second页面

states
///定义一个实例类型的变量存储传过来的实例
import 'package:get/get.dart';
import '../../../data/GoodsModel.dart';
class SecondState{
  Result Detail=Result();
}
controllers
///把传过来的实例赋值给state的Detail变量,这样就得到实例了
SecondState state =SecondState();
  @override
  void onInit() {
    super.onInit();
    state.Detail=Get.arguments;
  }
views
///通过实例调用数据,因为翻路由会自动刷新,所以不用Obx来刷新页面
body: Text(controller.state.Detail.title??'')

相关