2

在我的 Simpledialog 中将快餐栏添加到按下方法时,我遇到了下面的错误代码。[使用不包含 Scaffold 的上下文调用 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();
            }),
          ],
        ),
      ),
    );
  }
}
4

3 回答 3

5

解决方案 1:正如 Mazin Ibrahim 在评论Scaffold.of() 中提到的,使用不包含 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包,您还可以在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);
于 2019-05-28T09:01:49.627 回答
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);
          },
        ),
      ],
    );
  }
}

于 2020-04-10T12:35:39.840 回答
0

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

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

于 2020-12-16T06:30:52.547 回答