问题描述
我是Flutter的新手,我正在创建一个android应用程序,并且遇到了一些奇怪的情况,即在调用update方法时,snakebar显示,但在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,});
}
}
Widget _displaySnackBar(BuildContext context,String message) {
return SnackBar(
content: Text(message),action: SnackBaraction(
label: "Close",onpressed: () {
Scaffold.of(context).hideCurrentSnackBar();
},);
}
更新和创建都在_submitForm()方法中。支架上下文作为参数从HomeView(无状态类)页面(具有Scaffold小部件)传递到CategoryView(无状态类)页面,最后在AddEditCategory(有状态)页面中传递。为了建立类别列表,我将Provider与Consumer一起使用。 viewmodel已使用ChangeNotifier类进行了扩展,并且每个方法都具有notifyListeners()。如果需要的代码超出我的能力范围。
解决方法
处理SnackBar
的另一种方法是将GlobalKey
分配给Scaffold
小部件,然后使用key.currentState
属性获得ScaffoldState而不是使用{{1 }}功能。
Scaffold.of()
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
然后在需要显示Scaffold(
key: _scaffoldKey,body: Container(),);
时显示:
SnackBar
此链接here可以帮助
,我自己解决了快餐店的问题。在嵌套的小部件中传递了错误的上下文,并且还使用Builder来获取AppBar操作小部件列表的Scaffold上下文,在该位置上放置了IconButton来添加类别。