Puis-je créer quelque chose de similaire à Toasts dans Flutter? Juste une petite fenêtre de notification qui ne se présente pas directement à la face de l'utilisateur et ne verrouille pas ou ne fait pas disparaître la vue derrière elle?
Vous pouvez accéder au parent ScaffoldState
en utilisant Scaffold.of(context)
Puis fais quelque chose comme
Scaffold.of(context).showSnackBar(new SnackBar(
content: new Text("Sending Message"),
));
Snackbars sont les "Toast" officiels de la conception matérielle. Voir https://material.io/design/components/snackbars.html#usage
Voici un exemple pleinement fonctionnel:
import 'package:flutter/material.Dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: const 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'),
),
/// We use [Builder] here to use a [context] that is a descendant of [Scaffold]
/// or else [Scaffold.of] will return null
body: Builder(
builder: (context) => Center(
child: RaisedButton(
child: const Text('Show toast'),
onPressed: () => _showToast(context),
),
),
),
);
}
void _showToast(BuildContext context) {
final scaffold = Scaffold.of(context);
scaffold.showSnackBar(
SnackBar(
content: const Text('Added to favorite'),
action: SnackBarAction(
label: 'UNDO', onPressed: scaffold.hideCurrentSnackBar),
),
);
}
}
SnackBar
est certainement la bonne classe à utiliser, comme l'a souligné Darky.
Une chose délicate à propos de showSnackBar
consiste à accéder à ScaffoldState
, si vous essayez d'appeler showSnackBar
dans la méthode de construction où vous construisez votre Scaffold
.
Vous verrez peut-être une erreur comme celle-ci, qui comprend un texte expliquant comment résoudre le problème.
══╡ 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)
════════════════════════════════════════════════════════════════════════════════════════════════════
Vous pouvez soit passer un GlobalKey
à votre constructeur 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),
);
}
),
);
}
}
Ou vous pouvez utiliser un Builder
pour créer un BuildContext
qui est un enfant de l'échafaudage.
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),
);
}
),
);
}
}
Enfin, vous pouvez diviser votre widget en plusieurs classes, ce qui constitue la meilleure approche à long terme.
Utilisez ceci plugin
Fluttertoast.showToast(
msg: "This is Toast messaget",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIos: 1
);
pour afficher un message de pain grillé, vous pouvez utiliser le plugin flutterToast pour utiliser ce plugin
fluttertoast: ^3.1.0
$ flutter packages get
import 'package:fluttertoast/fluttertoast.Dart';
l'utiliser comme ça
Fluttertoast.showToast(
msg: "your message",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM // also possible "TOP" and "CENTER"
backgroundColor: "#e74c3c",
textColor: '#ffffff');
Pour plus d'informations, consultez this
Je voudrais fournir une solution alternative à l'utilisation de package flushbar. https://github.com/AndreHaueisen/flushbar
Comme le paquet dit: Utilisez ce paquet si vous avez besoin de plus de personnalisation pour notifier votre utilisateur. Pour les développeurs Android, il est conçu pour remplacer les toasts et les barres de type snack.
Une autre suggestion d'utiliser flushbar Comment afficher un snackbar après navigator.pop (contexte) dans Flutter?
Vous pouvez également définir flushbarPosition sur TOP ou 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);
Dans le cas où le paquet Fluttertoast donné jusqu'à présent ne fonctionne pas ... Ensuite, je vous suggère d'essayer pain grillé .
Il n’a pas de fioritures ni de cérémonie.
Ça fonctionne.
J'ai cependant remarqué un bogue dans l'exemple donné dans son fichier Readme:
Toast.show("Toast plugin app", duration: Toast.LENGTH_SHORT, gravity: Toast.BOTTOM);
Alors que la méthode nécessite un contexte. Alors, faites bien d'ajouter 'contexte' comme ceci:
Toast.show("Toast plugin app", context, duration: Toast.LENGTH_SHORT, gravity: Toast.BOTTOM);
Il est possible que cela ait été corrigé au moment où vous avez coché la case J'ai déjà soumis un PR.
Pour ceux qui recherchent une Toast
ce qui peut survivre aux changements de route, le SnackBar
pourrait ne pas être la meilleure option.
Regardez plutôt Overlay
.
Pour Android toasts graphiques d'origine, vous pouvez utiliser ceci: https://pub.dartlang.org/packages/fluttertoast
Fonctionne bien sur Android et iOS. entrez la description de l'image ici
https://pub.dev/packages/toast utiliser ceci pour le pain grillé, cette bibliothèque est assez facile à utiliser et fonctionne parfaitement pour iOS et Android,
Syntaxe pour l'émission Toast:
Toast.show("Toast plugin app", duration: Toast.LENGTH_SHORT, gravity: Toast.BOTTOM);
utiliser cette dépendance: toast: ^0.1.3
puis importer la dépendance de toast dans la page: import 'package:toast/toast.Dart';
puis sur onTap () du widget: Toast.show("Toast plugin app", context,duration: Toast.LENGTH_SHORT, gravity: Toast.BOTTOM);
dépendances:
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);