【源码篇】Flutter GetX深度剖析 | 我们终将走出自己的路(万字图文) (5)

此处精简很多代码,只展示回收机制的代码

class GetBuilder<T extends GetxController> extends StatefulWidget { final GetControllerBuilder<T> builder; final bool global; final String? tag; final bool autoRemove; final T? init; const GetBuilder({ Key? key, this.init, this.global = true, required this.builder, this.autoRemove = true, this.initState, this.tag, }) : super(key: key); @override GetBuilderState<T> createState() => GetBuilderState<T>(); } class GetBuilderState<T extends GetxController> extends State<GetBuilder<T>> with GetStateUpdaterMixin { T? controller; bool? _isCreator = false; VoidCallback? _remove; Object? _filter; @override void initState() { super.initState(); widget.initState?.call(this); var isRegistered = GetInstance().isRegistered<T>(tag: widget.tag); if (widget.global) { if (isRegistered) { controller = GetInstance().find<T>(tag: widget.tag); } else { controller = widget.init; GetInstance().put<T>(controller!, tag: widget.tag); } } else { controller = widget.init; controller?.onStart(); } } @override void dispose() { super.dispose(); widget.dispose?.call(this); if (_isCreator! || widget.assignId) { if (widget.autoRemove && GetInstance().isRegistered<T>(tag: widget.tag)) { GetInstance().delete<T>(tag: widget.tag); } } _remove?.call(); controller = null; _isCreator = null; _remove = null; _filter = null; } @override Widget build(BuildContext context) { return widget.builder(controller!); } }

代码里的逻辑还是相当清晰的,initState获取实例,dispose回收实例

通过GetBuilder上泛型获取相应GetXController实例

不存在:使用init传入的实例

存在:直接使用;init传入的实例无效

autoRemove可以控制是否自动回收GetXController实例

默认为true:默认开启自动回收

true:开启自动回收 false:关闭自动回收

刷新逻辑

这里仅保留刷新逻辑的相关代码,去掉了无需关注的代码

mixin GetStateUpdaterMixin<T extends StatefulWidget> on State<T> { void getUpdate() { if (mounted) setState(() {}); } } class GetBuilder<T extends GetxController> extends StatefulWidget { final GetControllerBuilder<T> builder; final bool global; final T? init; final Object? id; const GetBuilder({ Key? key, this.init, this.id, this.global = true, required this.builder, }) : super(key: key); @override GetBuilderState<T> createState() => GetBuilderState<T>(); } class GetBuilderState<T extends GetxController> extends State<GetBuilder<T>> with GetStateUpdaterMixin { T? controller; @override void initState() { super.initState(); ... if (widget.global) { if (isRegistered) { controller = GetInstance().find<T>(tag: widget.tag); } else { controller = widget.init; GetInstance().put<T>(controller!, tag: widget.tag); } } else { controller = widget.init; controller?.onStart(); } _subscribeToController(); } void _subscribeToController() { _remove?.call(); _remove = (widget.id == null) ? controller?.addListener( _filter != null ? _filterUpdate : getUpdate, ) : controller?.addListenerId( widget.id, _filter != null ? _filterUpdate : getUpdate, ); } void _filterUpdate() { var newFilter = widget.filter!(controller!); if (newFilter != _filter) { _filter = newFilter; getUpdate(); } } @override void didChangeDependencies() { super.didChangeDependencies(); widget.didChangeDependencies?.call(this); } @override void didUpdateWidget(GetBuilder oldWidget) { super.didUpdateWidget(oldWidget as GetBuilder<T>); if (oldWidget.id != widget.id) { _subscribeToController(); } widget.didUpdateWidget?.call(oldWidget, this); } @override Widget build(BuildContext context) { return widget.builder(controller!); } }

关键步骤

通过泛型获取注入的GetXController实例

添加监听代码

addListener:添加监听回调

addListenerId:添加监听回调,必须设置id,update刷新的时候也必须写上配套的id

监听代码:核心代码就是getUpdate方法,方法在 GetStateUpdaterMixin 中

getUpdate()逻辑就是 setState(),刷新当前GetBuilder

图示

GetBuilder

Update

触发逻辑还是很简单的,使用update即可

Ids:和上面的Getbuilder对应起来了,可刷新对应设置id的GetBuilder

condition:是否刷新一个判断条件,默认为true(假设必须某个id大于3才能刷新:update([1, 2, 3, 4], index > 3) )

abstract class GetxController extends DisposableInterface with ListNotifier { void update([List<Object>? ids, bool condition = true]) { if (!condition) { return; } if (ids == null) { refresh(); } else { for (final id in ids) { refreshGroup(id); } } } }

看下关键方法 refresh(),在ListNotifier类中

可以发现,_updaters中泛型就是一个方法

在GetBuilder中添加的监听就是一个方法参数,方法体里面就是 setState()

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zgyyyj.html