flutter - 数据持久化到数据库后,Snackbar 不显示
问题描述
我是 Flutter 的新手,我正在创建一个 android 应用程序并面临一些奇怪的情况,即在调用 update 方法时显示小吃栏但在 create 方法上不显示。两者(更新和创建)都在一种方法中,由 if else 条件分隔。为简洁起见,我省略了一些代码。这是代码:
class AddEditCategory extends StatefulWidget {
final BuildContext scaffoldContext;
AddEditCategory({
Key key,
@required this.scaffoldContext,
}) : super(key: key);
@override
_AddEditCategoryState createState() => _AddEditCategoryState();
}
class _AddEditCategoryState extends State<AddEditCategory> {
@override
Widget build(BuildContext context) {
return AlertDialog(
insetPadding: EdgeInsets.symmetric(horizontal: 0),
title: Text(
widget.title,
textAlign: TextAlign.center,
),
content: CategoryTextField(
controller: textEditingController),
actions: [
OutlineButtonAddNewCategory(
positiveAction: widget.positiveAction,
validateDialog: _validateDialog,
textEditingController: textEditingController,
categoryToEdit: widget.categoryToEdit,
scaffoldContext: widget.scaffoldContext,
),
OutlineButton(
child: Text(
widget.negativeAction,
style: TextStyle(color: Colors.redAccent),
),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
}
}
class OutlineButtonAddNewCategory extends StatelessWidget {
final String positiveAction;
final bool validateDialog;
final TextEditingController textEditingController;
final Category categoryToEdit;
final BuildContext scaffoldContext;
OutlineButtonAddNewCategory(
{this.positiveAction,
this.validateDialog,
this.textEditingController,
this.categoryToEdit,
this.scaffoldContext});
@override
Widget build(BuildContext context) {
return OutlineButton(
child: Text(
positiveAction,
style: TextStyle(
color: validateDialog ? Colors.blueAccent : Colors.grey,
),
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5.0),
),
onPressed: () async {
if (validateDialog) {
await _submitForm(scaffoldContext,
textEditingController.text.toString(), categoryToEdit);
Navigator.of(context).pop();
}
},
);
}
}
Future _submitForm(BuildContext scaffoldContext, String categoryName,
Category categoryToEdit) async {
CategoryViewModel categoryModel = locator<CategoryViewModel>();
Category category;
if (categoryToEdit != null) {
category = categoryToEdit;
category.id = categoryToEdit.id;
category.categoryName = categoryName;
category.updatedOn = DateTime.now().toIso8601String();
String message = "Category '$categoryName' updated successfully";
await categoryModel.updateCategory(category).then((value) => {
Scaffold.of(scaffoldContext).showSnackBar(
_displaySnackBar(scaffoldContext, message),
)
});
} else {
category = Category(categoryName: categoryName);
String message = "Category '$categoryName' saved successfully";
await categoryModel.createCategory(category).then((value) => {
Scaffold.of(scaffoldContext).showSnackBar(
_displaySnackBar(scaffoldContext, message),
),
});
}
}
Widget _displaySnackBar(BuildContext context, String message) {
return SnackBar(
content: Text(message),
action: SnackBarAction(
label: "Close",
onPressed: () {
Scaffold.of(context).hideCurrentSnackBar();
},
),
);
}
update 和 create 都在 _submitForm() 方法中。Scaffold 上下文作为参数从 HomeView(无状态类)页面(具有 Scaffold 小部件)传递到 CategoryView(无状态类)页面,最后在 AddEditCategory(有状态)页面中传递。为了构建类别列表,我将 Provider 与消费者一起使用。Viewmodel 已经扩展了 ChangeNotifier 类,并且每个方法都有 notifyListeners()。如果需要比我提供的更多的代码。
解决方案
另一种处理 a 的方法SnackBar
是将 a 分配GlobalKey
给Scaffold
小部件,然后使用该key.currentState
属性获取 ScaffoldState 而不是使用Scaffold.of()
函数。
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
Scaffold(
key: _scaffoldKey,
body: Container(),
);
然后每当您需要显示SnackBar
:
_scaffoldKey.currentState.showSnackBar(
SnackBar(
content: Text('Assign a GlobalKey to the Scaffold'),
duration: Duration(seconds: 3),
));
此处的此链接可以提供帮助
推荐阅读
- configuration - 轻量级 - 不需要的 HSTS
- c# - 如何使用反射动态获取对象属性的实例
- javascript - 错误:
属性 y1:预期长度,“NaN” - javascript - 在鼠标移动时增加两个 div 的高度
- sql - 比较两行与不同列中的匹配字段值
- python-3.x - spaCy is_oov 没有按预期工作
- mysql - 如何通过 node.js 提高 mysql 查询性能?
- html - 如何在知道容器和盒子的大小的情况下找到容器内每个盒子的百分比(6)
- javascript - 应用于 .ChartWrapper() 元素时的 Google Visualization .getSelection() 错误
- java - 如何使用按钮显示字符串并更改为下一个字符串(在列表中)?