resolveTree static method
Implementation
static RenderObjectElement? resolveTree(
Offset buttonOffset, BuildContext context) {
Element? currentPage;
final List<RenderObjectElement> inBounds = <RenderObjectElement>[];
final Rect focus =
Rect.fromLTWH(buttonOffset.dx, buttonOffset.dy, diameter, diameter);
// 记录根路由,用以过滤overlay
final ModalRoute<dynamic>? rootRoute = ModalRoute.of<dynamic>(context);
void filter(Element element) {
// 兼容IOS,IOS的MaterialApp会在Navigator后再插入一个PositionedDirectional控件,用以处理右滑关闭手势,遍历的时候跳过该控件
// ignore:
if (element.widget is! PositionedDirectional) {
if (element is RenderObjectElement &&
element.renderObject is RenderBox) {
final ModalRoute<dynamic>? route = ModalRoute.of<dynamic>(element);
// overlay不包含route信息,通过ModalRoute.of会获取到当前所在materialapp在其父节点内的route,此处对overlay做过滤。只能过滤掉直接添加在根MaterialApp的overlay,
// 并且该overlay的子widget不能包含materialApp或navigator
if (route != null && route != rootRoute) {
currentPage = element;
final RenderBox renderBox = element.renderObject as RenderBox;
if (renderBox.hasSize && renderBox.attached) {
final Offset offset = renderBox.localToGlobal(Offset.zero);
if (isOverlap(
focus,
Rect.fromLTWH(offset.dx, offset.dy, element.size!.width,
element.size!.height))) {
inBounds.add(element);
}
}
}
}
element.visitChildren(filter);
}
}
context.visitChildElements(filter);
RenderObjectElement? topElement;
final ModalRoute<dynamic>? route =
currentPage != null ? ModalRoute.of<dynamic>(currentPage!) : null;
for (final RenderObjectElement element in inBounds) {
if ((route == null || ModalRoute.of(element) == route) &&
checkSelected(topElement, element, buttonOffset)) {
topElement = element;
}
}
return topElement;
}