在 Flutter 的 SimpleDialog 中使用 Snackbar
在 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日
你可以从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); }, ), ], ); } }
解决方法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);