Как получить контекст в любой функции StatelessWidget?
Мы хотим показать AlertDialog после некоторой асинхронной обработки, такой как сетевые процессы.
При вызове showAlertDialog () из внешнего класса я хочу вызвать его без контекста. Есть хороший способ?
class SplashPage extends StatelessWidget implements SplashView {
BuildContext _context;
@override
Widget build(BuildContext context) {
this._context = context;
...
}
Я рассмотрел описанный выше метод, но меня беспокоят побочные эффекты.
Помогите
Мой текущий код
class SplashPage extends StatelessWidget implements SplashView {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: MyStoreColors.eats_white1_ffffff,
body: Center(
child: new SvgPicture.asset('assets/ic_splash.svg'),
),
);
}
@override
void showAlertDialog() {
showDialog<void>(
context: /*How to get context?*/,
builder: (BuildContext context) {
return AlertDialog(
title: Text('Not in stock'),
content: const Text('This item is no longer available'),
actions: <Widget>[
FlatButton(
child: Text('Ok'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
@override
void moveToHomeContainer() {
}
@override
void moveToLoginContainer() {
}
}
3 ответа
Вы должны запустить перестройку, когда событие async завершится, либо преобразуйте свой виджет в StatefulWidget
и позвони setState()
или используйте решение для управления состоянием, такое как Bloc.
Например, используя StatefulWidget
ваш код будет выглядеть так:
class SplashPage extends StatefulWidget {
@override
State<SplashPage> createState() => _SplashPageState();
}
class _SplashPageState extends State<SplashPage> implements SplashView {
bool _asynOpDone = false;
/// Call this when the async operation is done.
void _onAsynOpDone() => setState(() => _asyncOpDone = true);
@override
Widget build(BuildContext context) {
if (_asyncOpDone) showAlertDialog(context);
return Scaffold(
...,
///
);
}
@override
void showAlertDialog(BuildContext context) {
showDialog<void>(
context: context,
builder: ...,
);
}
}
Чтобы показать AlertDialog, вам нужен контекст, но в StatelessWidget у вас нет прямого доступа к нему, как в StatefulWidget.
Несколько вариантов [1]:
- передавая его как GlobalKey [2]
- передача контекста сборки в качестве параметра любой другой функции внутри StatelessWidget
- использовать службу для ввода диалога без контекста [3]
Ваше здоровье.
Вы можете применить концепцию шаблона Builder, чтобы упростить это.
Здесь есть небольшой пример.