【发布时间】:2021-10-20 10:34:30
【问题描述】:
当用户按下“保存”按钮时,我在对话框内显示一个 Snackbar。 Snackbar 确实显示在 Dialog 的底部,但它也显示在 Dialog 后面的屏幕上。我只想要对话框中的 Snackbar。
我尝试了这些可能的fixes:使用生成器;使用无状态小部件;使用 GlobalKey。
但是这些是在树中找不到脚手架时的修复,这似乎不是我遇到的问题,除非 Snackbar 显示在两个脚手架中(Home 中的那个)和对话框中的那个)。我认为 GlobalKey 会解决这个可能的问题,但它没有。无论如何,那些脚手架有不同的 BuildContexts。我在下面留下了打印语句以查看 BuildContext 哈希码。
这是我在调试控制台中得到的(我知道这是多余的,但我只是想看看在此过程中是否发生了一些切换):
MyApp context: 3
UserAccountToolbarItem build context: 194
UserAccountToolbarItem _buildDropDown context: 194
_UserPageState _showUser context: 327
_UserPageState _save context: 327
如果您运行下面的代码,您可以看到当我从应用程序主体或通过 AppBar 操作中的 PopupMenuButton 打开 Dialog 时,会发生同样的事情。 (在我的实际应用中,我使用的是 PopupMenuButton。)
如果有人对这里发生的事情有任何想法,我很想听听他们的意见。我错过了什么吗?
提前谢谢你!
Main.dart:
import 'package:flutter/material.dart';
import 'package:snackbars/user_account_toolbar_item.dart';
import 'package:snackbars/user_page.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
print('MyApp context: ${context.hashCode}');
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Snackbar Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: StatelessHome(),
);
}
}
class StatefulHome extends StatefulWidget {
@override
_StatefulHomeState createState() => _StatefulHomeState();
}
class _StatefulHomeState extends State<StatefulHome> {
@override
Widget build(BuildContext context) {
print('_StatefulHomeState context: ${context.hashCode}');
return Scaffold(
appBar: AppBar(
title: Text('Flutter Snackbar Demo Home Page with Stateful Home'),
actions: [UserAccountToolbarItem()],
),
body: Center(
child: ElevatedButton(
child: Text('Show dialog!'),
onPressed: () {
showDialog(
context: context,
builder: (BuildContext context) {
return Dialog(
child: UserPage(),
);
});
}),
));
}
}
User_Account_Toolbar_Item.dart:
import 'package:flutter/material.dart';
import 'package:snackbars/user_page.dart';
class UserAccountToolbarItem extends StatelessWidget {
void _showUser(context) {
print('UserAccountToolbarItem _showUser context: ${context.hashCode}');
showDialog(
context: context,
builder: (context) {
return Dialog(
child: Container(width: 480, child: UserPage()),
);
},
);
}
Widget _buildDropDown(BuildContext context) {
print('UserAccountToolbarItem _buildDropDown context: ${context.hashCode}');
return PopupMenuButton<Widget>(
icon: Icon(Icons.account_circle_sharp),
itemBuilder: (BuildContext context) => <PopupMenuEntry<Widget>>[
PopupMenuItem<Widget>(
value: Text('Sign Out'),
child: ListTile(title: Text('Dummy ListTile')),
),
PopupMenuItem<Widget>(
child: ListTile(
title: Text('CLICK ME'),
onTap: () => {
Navigator.pop(context),
_showUser(context)
},
),
),
],
);
}
@override
Widget build(BuildContext context) {
print('UserAccountToolbarItem build context: ${context.hashCode}');
return _buildDropDown(context);
}
}
User_Page.dart:
import 'package:flutter/material.dart';
class UserPage extends StatefulWidget {
@override
_UserPageState createState() => _UserPageState();
}
class _UserPageState extends State<UserPage> {
@override
Widget build(BuildContext context) {
print('_UserPageState _showUser context: ${context.hashCode}');
return Scaffold(
appBar: AppBar(
title: Text('User Account'),
actions: <Widget>[
MaterialButton(
onPressed: () => _save(),
child: Text(
'Save',
style: TextStyle(color: Colors.white),
),
),
],
),
body: Text('Dialog Body'),
);
}
void _save() async {
print('_UserPageState _save context: ${context.hashCode}');
try {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Something updated.'),
backgroundColor: Colors.green,
),
);
} catch (e) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Save failed: ${e.toString()}'),
backgroundColor: Colors.red),
);
}
}
}
【问题讨论】: