页面容器的视图管理
这一节我们分析页面容器的实现。通过源码对比,可以知道Boost参考了Flutter内部的Navigator实现,进行了相应的调整,更严格的说是继承了Navigator。
class BoostContainer extends Navigator
BoostContainer实现
页面容器的实现类是BoostContainer。类似的,他也新增了一些状态的概念:
- Init 初始化
- Appear 展示
- WillDisappear 即将消失
- Disappear 页面消失
- Destroy 页面销毁
- Background 置后台
- Foreground 置前台
这些概念虽然不难理解,但是甚至比原生还冗杂😂。
整个Navigator容器,涉及Widget,State和Observer,在boost中继承关系如下:
- BoostContainer 继承 Navigator
- BoostContainerState 继承 NavigatorState 重载了push,pop,maybePop等函数,提供了一个返回键函数
- ContainerNavigatorObserver 继承 NavigatorObserver ,新增了观察者的注册接口
栈操作
在自定义的页面容器中,主要重载的是路由的相关出栈、入栈操作。
pop拦截后,如果当前存在原生的Navigator视图栈,则优先弹出,如果不存在,则通过channel转发给了native;
/// boost_container.dart
@override
bool pop<T extends Object>([T result]) {
// ...
if (canPop()) {
return super.pop(result);
} else {
if (T is Map<String, dynamic>) {
FlutterBoost.singleton
.close(uniqueId, result: result as Map<String, dynamic>);
} else {
FlutterBoost.singleton.close(uniqueId);
}
}
return false;
}
对push的拦截和pop不同,push拦截只增加了对route的pre和post修饰,最终还是通过调用super,交给了原生的Navigator处理。
/// boost_container.dart
@override
Future<T> push<T extends Object>(Route<T> route) {
Route<T> newRoute;
/// ...
Future<T> future = super.push<T>(newRoute ?? route);
routerHistory.add(route);
/// ...
return future;
}
总的来说就是出栈需要考虑Navigator自身已经由Native控制的Overlay这一次页面容器,入栈则是使用原生Navigator逻辑。
页面Widget绑定
在Container中,我们没有看到build重载,上下文中,也不涉及页面构建逻辑。回顾下我们前面分析的嵌套关系图
那么Boost是如何实现的页面绑定关系?
在Flutter中,经常通过WidgetBuilder来实现视图的按需构建。这里Boost定义了一个页面配置的模型。
/// boost_container.dart
class BoostContainerSettings {
final String uniqueId;
final String name;
final Map params;
final WidgetBuilder builder;
const BoostContainerSettings(
{this.uniqueId = 'default',
this.name = 'default',
this.params,
this.builder});
}
其中包含一个builder,最终会透传给Navigator的builder属性,从而实现了Widget的绑定。setting配置在有页面push的时候动态生成,由函数_createContainerSettings负责。
/// container_coordinator.dart
final BoostContainerSettings routeSettings = BoostContainerSettings(
uniqueId: pageId,
name: name,
params: params,
builder: (BuildContext ctx) {
// ...
//Build a page using default builder.
if (page == null && _defaultPageBuilder != null) {
page = _defaultPageBuilder(name, params, pageId);
}
// ...
return page;
});
其他
处理页面的出栈入栈相关逻辑,BoostContainer中还添加了一些对栈状态的监听,主要是添加监听器和循环遍历,这里不再展开,相关接口为ContainerNavigatorObserver
。
当Widget dipose时销毁观察者和历史路由页面