Get打开新页面、弹窗无需BuildContext原理

543 阅读1分钟

查看Get.bottomSheet方法,发现底层是调用Navigator,context是通过GetNavigation.key获取到的

BuildContext? get overlayContext {
  BuildContext? overlay;
  key.currentState?.overlay?.context.visitChildElements((element) {
    overlay = element;
  });
  return overlay;
}

extension ExtensionBottomSheet on GetInterface {
  Future<T?> bottomSheet<T>(...) {
  return Navigator.of(overlayContext!, rootNavigator: useRootNavigator)
      .push(GetModalBottomSheetRoute<T>(
  ....
  ));
  }
}

key.currentState获取到的是NavigatorState,.overlay获取到的是_overlayKey.currentState

class NavigatorState {
  late GlobalKey<OverlayState> _overlayKey;
  OverlayState? get overlay => _overlayKey.currentState;

  @override
  Widget build(BuildContext context) {
    return HeroControllerScope.none(
      child: Listener(
        onPointerDown: _handlePointerDown,
        onPointerUp: _handlePointerUpOrCancel,
        onPointerCancel: _handlePointerUpOrCancel,
        child: AbsorbPointer(
          absorbing: false, // it's mutated directly by _cancelActivePointers above
          child: FocusScope(
            node: focusScopeNode,
            autofocus: true,
            child: UnmanagedRestorationScope(
              bucket: bucket,
              child: Overlay(
                key: _overlayKey,
                initialEntries: overlay == null ?  _allRouteOverlayEntries.toList(growable: false) : const <OverlayEntry>[],
              ),
            ),
          ),
        ),
      ),
    );
  }
}

然后.context获取到的是

class State {
  BuildContext get context {
    return _element!;
  }
  StatefulElement? _element;
}

.visitChildElements获取子Element,Element是BuildContext的实现

abstract class BuildContext {
  void visitChildElements(ElementVisitor visitor);
}

那么,GetNavigation.key是在哪里设置的呢?

在GetMaterialApp中创建了MaterialApp,并把GetNavigation中的key设置给navigatorKey

MaterialApp(
navigatorKey:
(navigatorKey == null ? Get.key : Get.addKey(navigatorKey!)),
)

总结

弹窗、打开新页面无需BuildContext是因为在MaterialApp中设置了navigatorKey,然后通过navigatorKey获取到当前最上层页面的BuildContext。