У меня есть StatefulWidget вверху (назовем его верхним виджетом), функция сборки которого выглядит примерно так:
@override
Widget build(BuildContext context) {
return new MaterialApp(
color: // some color,
theme: // some theme,
home: new Scaffold(
backgroundColor: // some color,
body: new Builder(builder: (context) {
_builderContext = context;
return new Column(
children: <Widget>[
new Expanded(
child: new MaterialApp(
color: // some color,
theme: // some theme,
title: 'title',
onGenerateRoute: _onRoute,
navigatorKey: _navigatorState,
navigatorObservers: observers,
),
),
... etc
Теперь где-нибудь в дочерних виджетах, сгенерированных _onRoute, я хочу вывести нижний лист с showModalBottomSheet(context, ...)
. Однако контекст, передаваемый в showModalBottomSheet, должен быть контекстом из Builder в методе сборки выше. Если я использую контекст, доступный для ребенка, лист выскакивает не на том нижнем якоре моего пользовательского интерфейса. Теперь ребенок уже может общаться с верхним виджетом с помощью GlobalKey. Однако в другом методе верхнего виджета я могу получить доступ только к его общему контексту. Передача этого контекста в showModalBottomSheet генерирует нулевой указатель.
После долгих исследований и проб и ошибок единственное решение, которое я придумал, - это кэшировать контекст в методе сборки (_builderContext = context;
), а затем использовать этот кешированный контекст для передачи его в showModalBottomSheet в другом моем методе верхнего виджета:
openBottomSheet() {
if (_builderContext != null) {
showModalBottomSheet(
context: _builderContext,
builder: (context) {
return // some bottom sheet content;
});
}
}
На данный момент это, кажется, работает довольно хорошо, но мне было интересно, есть ли более чистый способ сделать это?
Вопрос можно обобщить на то, как я могу получить доступ к контексту в дочерних виджетах в целом. Я попытался придумать решение InheritedWidget, но не мог понять, как я могу каким-то образом сделать Builder унаследованным виджетом, а затем использовать это для моей проблемы.
Любые идеи очень ценятся.
MaterialApp
экземпляр - person Rémi Rousselet   schedule 17.07.2018