当小部件是 MaterialApp 的直接 child 时,显示对话框不起作用
showing a dialog doesn't work when the widget is the direct child of MaterialApp
我正在尝试在 Flutter 中创建一个警告对话框,但该对话框在 MaterialApp 下不起作用,而是给出错误。下面是代码:
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Inputs and alerts'),
),
body: ElevatedButton(
child: const Text('Show Dialog'),
onPressed: () {
showDialog(
context: context,
builder: (_) {
return AlertDialog(
title: Text('This is a text'),
content: Text('this is the content'),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop(false);
},
child: Text('No'),
),
TextButton(
onPressed: () {
Navigator.of(context).pop(true);
},
child: Text('Yes'),
)
],
);
},
);
},
),
),
);
}
}
错误
但是当我将 ElevatedButton 提取到 stand-alone 小部件时,警报对话框工作正常。这是代码:
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Inputs and alerts'),
),
body: sn(),
),
);
}
}
class sn extends StatelessWidget {
const sn({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
body: ElevatedButton(
child: const Text('Show Dialog'),
onPressed: () {
showDialog(
context: context,
builder: (_) {
return AlertDialog(
title: Text('This is a text'),
content: Text('this is the content'),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop(false);
},
child: Text('No'),
),
TextButton(
onPressed: () {
Navigator.of(context).pop(true);
},
child: Text('Yes'),
)
],
);
},
);
},
),
);
}
}
输出
谁能告诉我这种行为的原因?非常感谢任何帮助。
发生这种情况是因为您只能调用 showDialog(context)
传递一个 BuildContext
,其中 MaterialApp
作为祖先部件。您在第一个示例中的 build() 方法 中访问的上下文是 context,它没有任何 MaterialApp
在上面。
就像您所做的那样,您可以通过将 Scaffold
提取到另一个小部件中以在构建方法中访问它的 BuildContext
来解决此问题。
另一种解决方案是使用 Builder
小部件。它向它的 child 公开了一个新的上下文,现在其中包含对其上方的任何小部件的引用(在本例中为 MaterialApp
)。
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Builder(builder: (context) {
return Scaffold(
appBar: AppBar(
title: const Text('Inputs and alerts'),
),
body: ElevatedButton(
child: const Text('Show Dialog'),
onPressed: () {
showDialog(
context: context,
builder: (_) {
return AlertDialog(
title: Text('This is a text'),
content: Text('this is the content'),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop(false);
},
child: Text('No'),
),
TextButton(
onPressed: () {
Navigator.of(context).pop(true);
},
child: Text('Yes'),
)
],
);
},
);
},
),
);
}),
);
}
}
我正在尝试在 Flutter 中创建一个警告对话框,但该对话框在 MaterialApp 下不起作用,而是给出错误。下面是代码:
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Inputs and alerts'),
),
body: ElevatedButton(
child: const Text('Show Dialog'),
onPressed: () {
showDialog(
context: context,
builder: (_) {
return AlertDialog(
title: Text('This is a text'),
content: Text('this is the content'),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop(false);
},
child: Text('No'),
),
TextButton(
onPressed: () {
Navigator.of(context).pop(true);
},
child: Text('Yes'),
)
],
);
},
);
},
),
),
);
}
}
错误
但是当我将 ElevatedButton 提取到 stand-alone 小部件时,警报对话框工作正常。这是代码:
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Inputs and alerts'),
),
body: sn(),
),
);
}
}
class sn extends StatelessWidget {
const sn({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
body: ElevatedButton(
child: const Text('Show Dialog'),
onPressed: () {
showDialog(
context: context,
builder: (_) {
return AlertDialog(
title: Text('This is a text'),
content: Text('this is the content'),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop(false);
},
child: Text('No'),
),
TextButton(
onPressed: () {
Navigator.of(context).pop(true);
},
child: Text('Yes'),
)
],
);
},
);
},
),
);
}
}
输出
谁能告诉我这种行为的原因?非常感谢任何帮助。
发生这种情况是因为您只能调用 showDialog(context)
传递一个 BuildContext
,其中 MaterialApp
作为祖先部件。您在第一个示例中的 build() 方法 中访问的上下文是 context,它没有任何 MaterialApp
在上面。
就像您所做的那样,您可以通过将 Scaffold
提取到另一个小部件中以在构建方法中访问它的 BuildContext
来解决此问题。
另一种解决方案是使用 Builder
小部件。它向它的 child 公开了一个新的上下文,现在其中包含对其上方的任何小部件的引用(在本例中为 MaterialApp
)。
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Builder(builder: (context) {
return Scaffold(
appBar: AppBar(
title: const Text('Inputs and alerts'),
),
body: ElevatedButton(
child: const Text('Show Dialog'),
onPressed: () {
showDialog(
context: context,
builder: (_) {
return AlertDialog(
title: Text('This is a text'),
content: Text('this is the content'),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop(false);
},
child: Text('No'),
),
TextButton(
onPressed: () {
Navigator.of(context).pop(true);
},
child: Text('Yes'),
)
],
);
},
);
},
),
);
}),
);
}
}