【发布时间】:2018-02-07 10:41:05
【问题描述】:
【问题讨论】:
标签: flutter dart toast android-toast
【问题讨论】:
标签: flutter dart toast android-toast
更新: Scaffold.of(context).showSnackBar 在 Flutter 2.0.0(稳定版)中已弃用
您可以使用ScaffoldMessenger.of(context) 访问父ScaffoldMessengerState。
然后做类似的事情
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text("Sending Message"),
));
小吃店是材料设计的官方“吐司”。请参阅Snackbars。
这是一个完整的示例:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: Home(),
);
}
}
class Home extends StatelessWidget {
const Home({
Key key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Snack bar'),
),
body: Center(
child: RaisedButton(
onPressed: () => _showToast(context),
child: const Text('Show toast'),
),
),
);
}
void _showToast(BuildContext context) {
final scaffold = ScaffoldMessenger.of(context);
scaffold.showSnackBar(
SnackBar(
content: const Text('Added to favorite'),
action: SnackBarAction(label: 'UNDO', onPressed: scaffold.hideCurrentSnackBar),
),
);
}
}
【讨论】:
showSnackBar() 的小部件应该有一个Scaffold 父级。
ScaffoldMessage.showSnackBar()。
使用this插件
Fluttertoast.showToast(
msg: "This is Toast messaget",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIos: 1
);
【讨论】:
Unhandled Exception: MissingPluginException(No implementation found for method showToast on channel PonnamKarthik/fluttertoast)
SnackBar 绝对是使用正确的类,正如 Darky 所指出的那样。
如果您尝试在构建 Scaffold 的构建方法中调用 showSnackBar,则有关 showSnackBar 的一个棘手的事情是到达 ScaffoldState。
您可能会看到这样的错误,其中包含一些说明如何解决问题的文字。
══╡ EXCEPTION CAUGHT BY GESTURE ╞═══════════════════════════════════════════════════════════════════
The following assertion was thrown while handling a gesture:
Scaffold.of() called with a context that does not contain a Scaffold.
No Scaffold ancestor could be found starting from the context that was passed to Scaffold.of(). This
usually happens when the context provided is from the same StatefulWidget as that whose build
function actually creates the Scaffold widget being sought.
There are several ways to avoid this problem. The simplest is to use a Builder to get a context that
is "under" the Scaffold. For an example of this, please see the documentation for Scaffold.of():
https://docs.flutter.io/flutter/material/Scaffold/of.html
A more efficient solution is to split your build function into several widgets. This introduces a
new context from which you can obtain the Scaffold. In this solution, you would have an outer widget
that creates the Scaffold populated by instances of your new inner widgets, and then in these inner
widgets you would use Scaffold.of().
A less elegant but more expedient solution is assign a GlobalKey to the Scaffold, then use the
key.currentState property to obtain the ScaffoldState rather than using the Scaffold.of() function.
The context used was:
MyHomePage
When the exception was thrown, this was the stack:
#0 Scaffold.of (package:flutter/src/material/scaffold.dart:444:5)
#1 MyHomePage.build.<anonymous closure> (/Users/jackson/Library/Developer/CoreSimulator/Devices/7072C907-DBAD-44FE-8F40-0257442C51D9/data/Containers/Data/Application/77FEC1A4-1453-442C-8208-96E0323DEFB2/tmp/so_scratch2Tkq9Jb/so_scratch2/lib/main.dart:23:24)
#2 _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:323:14)
#3 _InkResponseState.build.<anonymous closure> (package:flutter/src/material/ink_well.dart:375:30)
#4 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:102:24)
#5 TapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:149:9)
#6 TapGestureRecognizer.acceptGesture (package:flutter/src/gestures/tap.dart:119:7)
#7 GestureArenaManager.sweep (package:flutter/src/gestures/arena.dart:156:27)
#8 BindingBase&SchedulerBinding&GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:147:20)
#9 BindingBase&SchedulerBinding&GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:121:22)
#10 BindingBase&SchedulerBinding&GestureBinding._handlePointerEvent (package:flutter/src/gestures/binding.dart:101:7)
#11 BindingBase&SchedulerBinding&GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:64:7)
#12 BindingBase&SchedulerBinding&GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:48:7)
#13 _invoke1 (file:///b/build/slave/Mac_Engine/build/src/flutter/lib/ui/hooks.dart:100)
#14 _dispatchPointerDataPacket (file:///b/build/slave/Mac_Engine/build/src/flutter/lib/ui/hooks.dart:58)
Handler: onTap
Recognizer:
TapGestureRecognizer#69dbc(debugOwner: GestureDetector, state: ready)
════════════════════════════════════════════════════════════════════════════════════════════════════
您可以将 GlobalKey 传递给您的 Scaffold 构造函数:
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final key = new GlobalKey<ScaffoldState>();
return new Scaffold(
key: key,
floatingActionButton: new Builder(
builder: (BuildContext context) {
return new FloatingActionButton(
onPressed: () {
key.currentState.showSnackBar(new SnackBar(
content: new Text("Sending Message"),
));
},
tooltip: 'Increment',
child: new Icon(Icons.add),
);
}
),
);
}
}
或者您可以使用 Builder 创建一个 BuildContext,它是 Scaffold 的子级。
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Scaffold(
floatingActionButton: new Builder(
builder: (BuildContext context) {
return new FloatingActionButton(
onPressed: () {
Scaffold.of(context).showSnackBar(new SnackBar(
content: new Text("Sending Message"),
));
},
tooltip: 'Increment',
child: new Icon(Icons.add),
);
}
),
);
}
}
最后,您可以将小部件拆分为多个类,这是最好的长期方法。
【讨论】:
I/flutter ( 4965): The following assertion was thrown while handling a gesture: I/flutter ( 4965): type 'LabeledGlobalKey<ScaffoldState>' is not a subtype of type 'BuildContext' of 'context' where I/flutter ( 4965): LabeledGlobalKey is from package:flutter/src/widgets/framework.dart I/flutter ( 4965): ScaffoldState is from package:flutter/src/material/scaffold.dart I/flutter ( 4965): Scaffold is from package:flutter/src/material/scaffold.dart I/flutter ( 4965): BuildContext is from package:flutter/src/widgets/framework.dart
GlobalKey 作为参数,而需要 BuildContext。如果没有看到更多代码,我无法帮助您进一步调试。请发布引发异常的代码行,可能您只是没有使用正确的参数。
Builder 选项效果很好。遇到了这个问题,这为我解决了。
final key = new GlobalKey<ScaffoldState>(); 修复了它。
要显示 Toast 消息,您可以使用 FlutterToast 插件。要使用此插件,您必须:
fluttertoast: ^3.1.0
$ flutter packages get
import 'package:fluttertoast/fluttertoast.dart';
像这样使用它:
Fluttertoast.showToast(
msg: "your message",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM // Also possible "TOP" and "CENTER"
backgroundColor: "#e74c3c",
textColor: '#ffffff');
更多信息,请查看this。
【讨论】:
fluttertoast:^3.1.3
import 'package:fluttertoast/fluttertoast.dart';
Fluttertoast.showToast(
msg: "This is Center Short Toast",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIos: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0
);
【讨论】:
如果目前提供的 Fluttertoast 包不起作用,那么我建议你尝试toast。
它没有多余的装饰,也没有仪式。
它只是工作。
我注意到在其 README 文件中给出的示例中存在一个错误:
Toast.show("Toast plugin app", duration: Toast.LENGTH_SHORT, gravity: Toast.BOTTOM);
虽然该方法需要上下文。所以最好像这样添加“上下文”:
Toast.show("Toast plugin app", context, duration: Toast.LENGTH_SHORT, gravity: Toast.BOTTOM);
这有可能在您检查时已经修复。我已经提交了 PR。
【讨论】:
pub.dartlang.org/packages/fluttertoast 插件。这个更简洁 [简洁] 并且更易于定制。
我想提供一个替代解决方案来使用包flushbar。
正如包所说:如果您在通知用户时需要更多自定义,请使用此包。对于 Android 开发者来说,它是用来代替 toasts 和snackbars 的。
另一个使用flushbar的建议是How can I show a snackbar after navigator.pop(context) in Flutter?
您还可以将 flushbarPosition 设置为 TOP 或 BOTTOM:
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);
【讨论】:
导入库fluttertoast:3.1.3
像下面这样使用它:
Fluttertoast.showToast(
msg: "Hello, World!",
textColor: Colors.white,
toastLength: Toast.LENGTH_SHORT,
timeInSecForIos: 1,
gravity: ToastGravity.BOTTOM,
backgroundColor: Colors.indigo,
);
【讨论】:
对于 Flutter 中的 toast 消息,使用 bot_toast 库。这个库提供了一个功能丰富的,对显示通知、文本、加载、附件等的支持。Toast
【讨论】:
在 Flutter 应用中显示 toast 有三种方式。
我会告诉你我知道的所有三种方式,然后选择你想使用的方式。我会推荐第二个。
1:使用外部包。
这是第一种在 Flutter 应用中显示 toast 的最简单方法。
首先,你必须将这个包添加到文件pubspec.YAML:
flutter_just_toast:^version_here
然后将包导入到你要展示 toast 的文件中。
'package:flutter_just_toast/flutter_just_toast.dart';
最后一步显示吐司。
Toast.show(message: "Your toast message",
duration: Delay.SHORT,
textColor: Colors.black);
2:使用官方方式。
这个方法也很简单,但你必须处理它。我并不是说它简单干净很难,我会推荐这种方法。
对于这种方法,你所要做的就是使用下面的代码来展示 toast。
Scaffold.of(context).showSnackBar(SnackBar(
content: Text("Sending Message"),
));
但请记住,您必须使用脚手架上下文。
3:使用原生 API。
现在,当您已经拥有上述两种方法时,此方法不再有意义。使用这种方法,你必须为 Android 和 iOS 编写原生代码,然后将其转换为插件,然后就可以开始了。
这种方法会消耗你的时间,你必须重新发明轮子。已经发明出来了。
【讨论】:
将 flutter_just_toast 添加到您的 Pubspecs.yaml 文件中的依赖项中。
依赖关系:
flutter_just_toast: ^1.0.1
接下来将包导入你的类:
import 'package:flutter_just_toast/flutter_just_toast.dart';
用消息实现 Toast:
Toast.show(message: "Your toast message",
duration: Delay.SHORT,
textColor: Colors.black);
【讨论】:
只需在 onTap 和 onPress 等任何事件中使用 SnackBar(content: Text("hello"),)。
您可以在 Display a snackbar 上阅读有关 Snackbar 的更多信息。
【讨论】:
对于那些正在寻找可以在路线变化中幸存的Toast 的人来说,SnackBar 可能不是最佳选择。
改为查看Overlay。
【讨论】:
你可以使用这个包:toast
toast: ^0.1.5
import 'package:toast/toast.dart';
Toast.show("Toast plugin app", context, duration: Toast.LENGTH_SHORT, gravity: Toast.BOTTOM);
【讨论】:
Get the Flutter toast package here
将此包添加到文件pubspec.yaml中的项目依赖项中。
然后,只要您希望显示 Toast,例如点击按钮:
Toast.show("Toast plugin app", context, duration: Toast.LENGTH_SHORT, gravity: Toast.BOTTOM);
【讨论】:
您可以使用库“fluttertoast”。为此,请将其添加到 pubspec.yaml 文件中,例如:
dependencies:
fluttertoast: ^3.1.0
然后将该库导入您需要 toast 的 .dart 文件中并编写代码。例如,参考以下代码:
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
class ToastExample extends StatefulWidget {
@override
_ToastExampleState createState() {
return _ToastExampleState();
}
}
class _ToastExampleState extends State {
void showToast() {
Fluttertoast.showToast(
msg: 'Some text',
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIos: 1,
backgroundColor: Colors.red,
textColor: Colors.white
);
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Toast Tutorial',
home: Scaffold(
appBar: AppBar(
title: Text('Toast Tutorial'),
),
body: Padding(
padding: EdgeInsets.all(15.0),
child: Center(
child: RaisedButton(
child: Text('Press to show'),
onPressed: showToast,
),
),
)
),
);
}
}
void main() => runApp(ToastExample());
【讨论】:
为此,有不同的版本。
首先,你可以使用 SnackBar,它是 Flutter 中的一个小部件。
您可以使用诸如 toast 之类的库 - flutter_toast 来自 pub.dev。
第三个版本是创建您的自定义小部件。它可以在 Flutter 中使用 Overlay 小部件和 Animation 创建。
您可以阅读本教程以了解更多信息。这里是a link。
【讨论】:
Scaffold.of(context).showSnackBar(...) 的答案在大多数情况下都不起作用。
我建议最佳方法是在类中声明一个scaffoldState键并将其分配给Scaffold,如下所示:
GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
然后
Scaffold(
key: _scaffoldKey,
...
)
当您想显示 Snackbar 时,请执行以下操作:
_scaffoldKey.currentState.showSnackBar(SnackBar(
content: Text("This works!"),
));
【讨论】:
使用这个:
Fluttertoast.showToast(
msg: "This is a Toast message",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIos: 1
);
【讨论】:
对于Android原图toast,可以使用这个:https://pub.dartlang.org/packages/fluttertoast
在 Android 和 iOS 上运行良好。
【讨论】:
使用https://pub.dev/packages/toast 表示敬酒。这个库非常易于使用,并且非常适用于 iOS 和 Android。
显示 Toast 的语法:
Toast.show("Toast plugin app", duration: Toast.LENGTH_SHORT, gravity: Toast.BOTTOM);
【讨论】:
依赖关系:
flutter_just_toast: ^1.0.1
import 'package:flutter_just_toast/flutter_just_toast.dart';
Toast.show(
message: "Your toast message",
duration: Delay.SHORT,
textColor: Colors.black);
【讨论】:
使用这个依赖:
toast: ^0.1.3
然后在页面中导入toast的依赖:
import 'package:toast/toast.dart';
然后在小部件的 onTap() 上:
Toast.show("Toast plugin app", context, duration:Toast.LENGTH_SHORT, gravity: Toast.BOTTOM);
【讨论】:
Flutter 中没有任何用于 toast 的小部件。你可以去this plugin。
用例:
Fluttertoast.showToast(
msg: "My toast message",
textColor: Colors.white,
toastLength: Toast.LENGTH_SHORT,
timeInSecForIos: 1,
gravity: ToastGravity.BOTTOM,
backgroundColor: Colors.indigo,);
【讨论】:
导入cupertino_icons: ^0.1.2 并编写以下代码:
showToast(BuildContext context, String message) {
showDialog(
context: context,
builder: (BuildContext context) {
return CupertinoAlertDialog(
title: Text("Name of App",
content: Text(message,
actions: <Widget>[
FlatButton(
child: Text("OK"),
onPressed: () {
Navigator.of(context).pop();
},
)
],
);
});
【讨论】:
} 和三个)s 似乎不见了。
很简单:
我们只需要安装 Flutter toast 包。 请参阅以下文档: https://pub.dev/packages/fluttertoast
在安装选项卡中,您将获得必须将其粘贴到 pubspec.yaml 文件中然后安装的依赖项。
在此之后,只需导入包:
import 'package:fluttertoast/fluttertoast.dart';
与上一行类似。
然后通过使用 FlutterToast 类,您可以使用您的 fluttertoast。
你已经完成了!!!
【讨论】:
您可以使用Flutter commons package 在 Flutter 应用程序中显示不同类型的 toast,如成功、错误、警告和信息。
successToast("Success Message");
【讨论】:
您可以使用this link 在 Flutter 中显示 Toast。
将其用作:
void method1(){
Fluttertoast.showToast(
msg: "This is Add Button",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 1,
backgroundColor: Colors.blueGrey,
textColor: Colors.white,
fontSize: 14.0
);
}
【讨论】:
在 Flutter 中显示 Toast 消息非常容易:
Scaffold.of(context).showSnackBar(SnackBar(
content: Text("Toast Text Here"),
));
【讨论】: