如何在StatelessWidget的any函数中获取上下文?
How to get context in the any function of StatelessWidget?
我们希望在一些异步处理(例如网络进程)之后显示一个 AlertDialog。
从外部 class 调用 '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() {
}
}
您应该在异步事件完成时触发重建,将您的小部件转换为 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 中那样直接访问它。
几个选项是:
- 将其作为 GlobalKey 传递
- 将构建上下文作为参数传递给 StatelessWidget 中的任何其他函数
- 使用服务在没有上下文的情况下注入对话
干杯。
您可以应用构建器模式概念来简化这一点。
这里有一个小例子。
我们希望在一些异步处理(例如网络进程)之后显示一个 AlertDialog。
从外部 class 调用 '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() {
}
}
您应该在异步事件完成时触发重建,将您的小部件转换为 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 中那样直接访问它。
几个选项是
- 将其作为 GlobalKey 传递
- 将构建上下文作为参数传递给 StatelessWidget 中的任何其他函数
- 使用服务在没有上下文的情况下注入对话
干杯。
您可以应用构建器模式概念来简化这一点。
这里有一个小例子。