为什么在
GetxController里调用upate()方法就能更新UI?答案其实就一句话:因为GetBuilder其实是一个StatefulWidget,而update()其实就是变相的调用了setState((){})
太长不看版请看前言。
在使用Get的时候我喜欢用GetBuilder而不是Obx(之前也没仔细研究原理啥的,反正作者说的是GetBuilder性能更好),但是其实使用Obx我认为应该也差不了多少,个人选择而已。
我一般是这么写页面的↓
UI页面:
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'test_logic.dart';
class TestPage extends StatelessWidget {
TestPage({super.key});
final TestLogic logic = Get.put(TestLogic());
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Hello get'),
),
body: GetBuilder<TestLogic>(builder: (logic) {
return Text('count is: ${logic.count}');
}),
floatingActionButton: FloatingActionButton(
onPressed: logic.add,
child: const Icon(Icons.add),
),
);
}
}
GetxController页面:
import 'package:get/get.dart';
class TestLogic extends GetxController {
int count = 0;
void add() {
count++;
update();
}
}
点击加号就能刷新UI了!但是,为什么可以刷新页面呢?
正文开始(由于只探究最简单的原理,很多无关的代码已省略)
GetBuilder其实是一个StatefulWidget的封装类而已,本质还是一个StatefulWidget。
上源码:
// 这里就是给一个返回Widget的方法取了一个别名而已
typedef GetControllerBuilder<T extends DisposableInterface> = Widget Function(
T controller);
class GetBuilder<T extends GetxController> extends StatefulWidget {
final GetControllerBuilder<T> builder;
@override
GetBuilderState<T> createState() => GetBuilderState<T>();
}
class GetBuilderState<T extends GetxController> extends State<GetBuilder<T>> {
T? controller;
@override
void initState() {
controller = GetInstance().find<T>(tag: widget.tag);
// 这个addListener在GetxController定义的,下面有写
controller?.addListener((){
if (mounted) setState(() {});
})
}
@override
Widget build(BuildContext context) {
return widget.builder(controller!);
}
}
上面就是GetBuilder的核心代码,剔除了各种检查与其他id、tag等等的功能。从里面我们可以看出在initState里给controller添加了一个更新UI的方法setState(() {}),所以在controller里就可以更新UI了。
本文到此结束,但是还有对知识渴望的(不死心的)同学还是继续来看看GetxController吧:
typedef GetStateUpdate = void Function();
abstract class GetxController {
List<GetStateUpdate?>? _updaters = <GetStateUpdate?>[];
void update([List<Object>? ids, bool condition = true]) {
refresh();
}
void refresh() {
_notifyUpdate();
}
void _notifyUpdate() {
for (var element in _updaters!) {
element!();
}
}
// 这里在GetBuilderState里添加的方法
Disposer addListener(GetStateUpdate listener) {
_updaters!.add(listener);
return ...;
}
}
get已学会,下一个~