[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??'')