SimpleDialog Flutter中的小吃店

时间:2019-02-10 14:51:08

标签: flutter snackbar simpledialog

在我的Simpledialog的按一下方法中添加一个快餐栏时,我在下面遇到错误代码。 [Scaffold.of()在不包含脚手架的上下文中调用。]

我想就如何提供正确的环境来寻求您的建议。

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<AlertApp> {


  SimpleDialog _simdalog;

  void sDialog(){
    _simdalog = new SimpleDialog(
      title: new Text("Add To Shopping Cart"),
      children: <Widget>[
        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: <Widget>[
        new RaisedButton(
            child: new Text("Add to Shopping Cart [Simple]"),
            onPressed:(){
              sDialog();
            }),
          ],
        ),
      ),
    );
  }
}

3 个答案:

答案 0 :(得分:0)

解决方案1:正如Mazin Ibrahim在评论Scaffold.of() called with a context that does not contain a Scaffold

中所述
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
...
Scaffold(
  key: _scaffoldKey,
...
onPressed: () {

                      _scaffoldKey.currentState.showSnackBar(
                          SnackBar(
                            content: Text('Purchase Successful'),
                            duration: Duration(seconds: 3),
                          ));
              }

解决方案2: 借助软件包冲洗栏,您还可以在顶部显示通知
Flushbar链接:https://github.com/AndreHaueisen/flushbar
另一个建议使用冲洗栏How to show snackbar after navigator.pop(context) in Flutter? enter image description here

    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);

答案 1 :(得分:0)

您可以从showDialog方法返回布尔值,并使用它来确定是否显示小吃栏:

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: <Widget>[
            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<bool>(
          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: <Widget>[
        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);
          },
        ),
      ],
    );
  }
}

答案 2 :(得分:0)

您应该在showDialog内创建一个Scaffold小部件,并在该Scaffold的子级中创建一个Builder小部件,并将上下文作为参数传递。

 void sDialog({BuildContext context}){
     
    _simdalog = new SimpleDialog(
      title: new Text("Add To Shopping Cart"),
      children: <Widget>[
        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 GestureDetector(
          onTap: (){Navigator.of(context).pop();},
          child: Scaffold(
            body: Builder(
                builder: (context){
                    return  _simdalog(context: context);
                }
            ),  
         ),);
    });
  }