了解了navigator的大致原理钞馁,Navigator是需要MaterialApp支持的,在其內(nèi)部才能使用匿刮。
Navigator也是一個(gè)Widget僧凰,他提供一個(gè)of方法使得子孫widget可以取到他的state。
static NavigatorState of(
BuildContext context, {
bool rootNavigator = false,
bool nullOk = false,
}) {...
: context.ancestorStateOfType(const TypeMatcher<NavigatorState>());
...
return navigator;
}
of方法中調(diào)用ancestorStateOfType方法熟丸,向上遍歷父element训措,找到Navigator的element就把他的state返回,state中封裝了各種push光羞、pop方法
@override
State ancestorStateOfType(TypeMatcher matcher) {
assert(_debugCheckStateIsActiveForAncestorLookup());
Element ancestor = _parent;
while (ancestor != null) {
if (ancestor is StatefulElement && matcher.check(ancestor.state))
break;
ancestor = ancestor._parent;
}
final StatefulElement statefulAncestor = ancestor;
return statefulAncestor?.state;
}
為啥Navigator可以隨意增刪widget呢隙弛,其實(shí)他內(nèi)部維護(hù)了一個(gè)用Overlay擴(kuò)展的Stack,push粗糙的說其實(shí)就是往stack中配置多一個(gè)widget狞山,然后rebuild全闷。但是Stack是會(huì)把整個(gè)widgetList都進(jìn)行繪制的,這樣連續(xù)push頁(yè)面后萍启,會(huì)爆炸的总珠。Overlay就是用來解決Stack的不足的,Overlay會(huì)把push的頁(yè)面進(jìn)行分類勘纯,是否需是否透明(如果透明局服,則下層widget也要參與繪制,反之不用)驳遵、要保存狀態(tài)(如果不需要淫奔,那么在上層widget不透明的情況下,可以直接扔掉)堤结。分類后唆迁,只有需要繪制的widget會(huì)按照順序配置到Stack中rebuild。
以上是Navigator工作的簡(jiǎn)要描述竞穷。
通過了解Navigator的工作原理唐责,可以看到,核心是Overlay瘾带,要自定義一個(gè)widget支持布局push鼠哥、pop(類似安卓碎片的效果),那么完全可以把Overlay剝出來看政,Overlay本身支持of方法從子widget中獲取他的state朴恳,他的state也提供了insert方法,可以插入一個(gè)widget允蚣。