KeepAlive
KeepAlive通过设置parentData(KeepAliveParentDataMixin类型)的keepAlive参数,控制RenderSliverMultiBoxAdaptor中_keepAliveBucket存储child RenderBox。
//用于SliverWithKeepAliveWidget类型小部件,比如SliverGrid、SliverList
class KeepAlive extends ParentDataWidget<SliverWithKeepAliveWidget>
class SliverMultiBoxAdaptorParentData extends SliverLogicalParentData with ContainerParentDataMixin<RenderBox>, KeepAliveParentDataMixin
class RenderSliverMultiBoxAdaptor
void _createOrObtainChild(int index, { RenderBox after }) {
invokeLayoutCallback<SliverConstraints>((SliverConstraints constraints) {
assert(constraints == this.constraints);
if (_keepAliveBucket.containsKey(index)) {
final RenderBox child = _keepAliveBucket.remove(index);
final SliverMultiBoxAdaptorParentData childParentData = child.parentData;
assert(childParentData._keptAlive);
dropChild(child);
child.parentData = childParentData;
insert(child, after: after);
childParentData._keptAlive = false;
} else {
_childManager.createChild(index, after: after);
}
});
}
void _destroyOrCacheChild(RenderBox child) {
final SliverMultiBoxAdaptorParentData childParentData = child.parentData;
if (childParentData.keepAlive) {
assert(!childParentData._keptAlive);
remove(child);
_keepAliveBucket[childParentData.index] = child;
child.parentData = childParentData;
super.adoptChild(child);
childParentData._keptAlive = true;
} else {
assert(child.parent == this);
_childManager.removeChild(child);
assert(child.parent == null);
}
}
AutomaticKeepAlive
通过监听KeepAliveNotification设置_keepingAlive参数,从而设置build的时候KeepAlive的keepAlive参数
AutomaticKeepAliveClientMixin
要和AutomaticKeepAlive配合使用,像PageView等的小部件会自动给其child嵌套AutomaticKeepAlive,此时如果child混合AutomaticKeepAliveClientMixin,则可以通过AutomaticKeepAliveClientMixin发送KeepAliveNotification通知实现keepAlive效果
mixin AutomaticKeepAliveClientMixin<T extends StatefulWidget> on State<T> {
KeepAliveHandle _keepAliveHandle;
void _ensureKeepAlive() {
assert(_keepAliveHandle == null);
_keepAliveHandle = KeepAliveHandle();
KeepAliveNotification(_keepAliveHandle).dispatch(context);
}
@protected
bool get wantKeepAlive;
@protected
void updateKeepAlive() {
if (wantKeepAlive) {
if (_keepAliveHandle == null)
_ensureKeepAlive();
} else {
if (_keepAliveHandle != null)
_releaseKeepAlive();
}
}
@override
void initState() {
super.initState();
if (wantKeepAlive)
_ensureKeepAlive();
}
网友评论