在 Flutter 的 SimpleDialog 中使用 Snackbar

11 浏览
0 Comments

在 Flutter 的 SimpleDialog 中使用 Snackbar

当我在我的Simpledialog的on-pressed方法中添加一个snackbar时,遇到了下面的错误代码。

[Scaffold.of() called with a context that does not contain a Scaffold.]

我想请教您如何提供正确的上下文来解决它。

import 'package:flutter/material.dart';
void main() {
  runApp(new MaterialApp(home: new AlertApp()));
}
class AlertApp extends StatefulWidget {
  @override
  _AlertAppState createState() => _AlertAppState();
}
class _AlertAppState extends State {
  SimpleDialog _simdalog;
  void sDialog(){
    _simdalog = new SimpleDialog(
      title: new Text("Add To Shopping Cart"),
      children: [
        new SimpleDialogOption(
          child: new Text("Yes"),
          onPressed: (){
            final snackBar = SnackBar(content: Text('Purchase Successful'));
            Scaffold.of(context).showSnackBar(snackBar);
          },
        ),
        new SimpleDialogOption(
          child: new Text("Close"),
          onPressed:() {Navigator.pop(context);},
        ),
      ],
    );
    showDialog(context: context, builder: (BuildContext context){
      return _simdalog;
    });
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: new Center(
        child: Column(
          mainAxisSize: MainAxisSize.max,
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
        new RaisedButton(
            child: new Text("Add to Shopping Cart [Simple]"),
            onPressed:(){
              sDialog();
            }),
          ],
        ),
      ),
    );
  }
}

admin 更改状态以发布 2023年5月20日
0
0 Comments

你可以从showDialog方法中返回一个bool值,并使用它来确定是否显示Snackbar:

void main() {
  runApp(MaterialApp(
    home: AlertApp(),
  ));
}
class AlertApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.max,
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            MyShoppingButton(),
          ],
        ),
      ),
    );
  }
}
// Separate out the button from _AlertAppState so that the call to
// showSnackBar comes from a different BuildContext
class MyShoppingButton extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return RaisedButton(
      child: Text("Add to Shopping Cart [Simple]"),
      // Use an async onPressed method so that we can wait for the
      // result from the dialog before deciding whether to show the snackbar
      onPressed: () async {
        bool result = await showDialog(
          context: context,
          builder: (BuildContext context) {
            return MyShoppingDialog();
          },
        );
        // Check if result is null below as Flutter will throw Exception if
        // tries determining whether to enter an if branch will a null boolean
        if (result != null && result) {
          final snackBar = SnackBar(content: Text('Purchase Successful'));
          Scaffold.of(context).showSnackBar(snackBar);
        }
      },
    );
  }
}
class MyShoppingDialog extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return SimpleDialog(
      title: Text("Add To Shopping Cart"),
      children: [
        SimpleDialogOption(
          child: Text("Yes"),
          onPressed: () {
            // Pop with a result of true so that MyShoppingButton
            // knows to show snackbar. In any other case
            // (including the user dismissing the dialog), MyShoppingButton
            // null receive null, and so will not show the snackbar
            Navigator.of(context).pop(true);
          },
        ),
        SimpleDialogOption(
          child: Text("Close"),
          onPressed: () {
            Navigator.pop(context);
          },
        ),
      ],
    );
  }
}

0
0 Comments

解决方法1:像Mazin Ibrahim在评论中提到的一样Scaffold.of()被使用在不包含Scaffold的上下文中

final GlobalKey _scaffoldKey = new GlobalKey();
...
Scaffold(
  key: _scaffoldKey,
...
onPressed: () {
                      _scaffoldKey.currentState.showSnackBar(
                          SnackBar(
                            content: Text('Purchase Successful'),
                            duration: Duration(seconds: 3),
                          ));
              }

解决方法2:使用Flushbar包,你也可以在顶部展示通知
Flushbar链接:https://github.com/AndreHaueisen/flushbar
另一个建议使用Flushbar:如何在Flutter中在navigator.pop(context)之后显示snackbar?
输入图像描述这里

    Flushbar(
      title: "Hey Ninja",
      message: "Lorem Ipsum is simply dummy text of the printing and typesetting industry",
      flushbarPosition: FlushbarPosition.TOP,
      flushbarStyle: FlushbarStyle.FLOATING,
      reverseAnimationCurve: Curves.decelerate,
      forwardAnimationCurve: Curves.elasticOut,
      backgroundColor: Colors.red,
      boxShadows: [BoxShadow(color: Colors.blue[800], offset: Offset(0.0, 2.0), blurRadius: 3.0)],
      backgroundGradient: LinearGradient(colors: [Colors.blueGrey, Colors.black]),
      isDismissible: false,
      duration: Duration(seconds: 4),
      icon: Icon(
        Icons.check,
        color: Colors.greenAccent,
      ),
      mainButton: FlatButton(
        onPressed: () {},
        child: Text(
          "CLAP",
          style: TextStyle(color: Colors.amber),
        ),
      ),
      showProgressIndicator: true,
      progressIndicatorBackgroundColor: Colors.blueGrey,
      titleText: Text(
        "Hello Hero",
        style: TextStyle(
            fontWeight: FontWeight.bold, fontSize: 20.0, color: Colors.yellow[600], fontFamily: "ShadowsIntoLightTwo"),
      ),
      messageText: Text(
        "You killed that giant monster in the city. Congratulations!",
        style: TextStyle(fontSize: 18.0, color: Colors.green, fontFamily: "ShadowsIntoLightTwo"),
      ),
    )..show(context);

0