查看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。