数据保存在数据库中后不显示 Snackbar

Snackbar not displaying after data is persisted in database

我是 Flutter 的新手,我正在创建一个 android 应用程序并遇到一些奇怪的情况,即调用更新方法时显示小吃栏但不显示创建方法。两者(更新和创建)都在一种方法中,由 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();
      },
    ),
  );
}

更新和创建都在_submitForm() 方法中。脚手架上下文作为参数从具有脚手架小部件的 HomeView(stateless class) 页面传递到 CategoryView(stateless class) 页面,最后传递到 AddEditCategory(stateful) 页面。为了构建类别列表,我将 Provider 与消费者一起使用。 Viewmodel 已使用 ChangeNotifier class 进行扩展,并且每个方法都有 notifyListeners()。如果需要的代码比我能提供的更多。

另一种处理 SnackBar 的方法是将 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),
  ));

这个linkhere可以帮助

我自己解决了snackbar的问题。在嵌套小部件中传递了错误的上下文,还使用 ​​Builder 获取 AppBar 操作小部件列表的脚手架上下文,其中放置了 IconButton 以添加类别。