首页 > 解决方案 > 数据持久化到数据库后,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()。如果需要比我提供的更多的代码。

标签: flutterandroid-snackbar

解决方案


另一种处理 a 的方法SnackBar是将 a 分配GlobalKeyScaffold小部件,然后使用该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),
  ));

此处的此链接可以提供帮助


推荐阅读