Puis-je créer quelque chose de similaire à Toasts dans Flutter ?
Juste une minuscule fenêtre de notification qui n'est pas directement dans le visage de l'utilisateur et qui ne verrouille pas ou n'estompe pas la vue derrière elle.
Puis-je créer quelque chose de similaire à Toasts dans Flutter ?
Juste une minuscule fenêtre de notification qui n'est pas directement dans le visage de l'utilisateur et qui ne verrouille pas ou n'estompe pas la vue derrière elle.
UPDATE : Scaffold.of(context).showSnackBar
est déprécié dans Flutter 2.0.0 (stable)
Vous pouvez accéder au parent ScaffoldMessengerState
en utilisant ScaffoldMessenger.of(context)
.
Ensuite, faites quelque chose comme
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text("Sending Message"),
));
Les Snackbars sont les "Toast" officiels du Material Design. Voir Snackbars .
Voici un exemple qui fonctionne parfaitement :
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),
),
);
}
}
Comment cela doit-il être intégré dans un onPressed par exemple ? J'ai essayé et rien ne s'affiche à l'écran.
Eh bien, je ne suis jamais rentré dans le moule et je sais que "officiel" ne veut pas dire absolu ! !! La Snackbar n'est pas du tout adaptée à l'interface utilisateur de mon application, c'est pourquoi je ne l'utilise pas et je mets toujours en place les anciennes notifications flottantes de type popup. Je pense qu'il est très facile pour les utilisateurs de rater les notifications de la Snackbar (surtout s'ils n'y sont pas habitués) ; mais il n'est pas facile de rater une popup flottant au milieu, en haut ou en bas de l'écran.
Utilisez ce plugin
Fluttertoast.showToast(
msg: "This is Toast messaget",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIos: 1
);
Vous devez d'abord ajouter la dépendance Fluttertoast dans le fichier pubspec.yaml. Le lien vers la dépendance est ici [link] ( pub.dartlang.org/packages/fluttertoast ). Vous pouvez alors utiliser le code ci-dessus
Unhandled Exception: MissingPluginException(No implementation found for method showToast on channel PonnamKarthik/fluttertoast)
SnackBar
est définitivement la bonne classe à utiliser, comme l'a souligné Darky.
Une chose délicate à propos de showSnackBar
est d'arriver à la 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 Scaffold
constructeur :
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 pourriez diviser votre widget en plusieurs classes, ce qui constitue la meilleure approche à long terme.
J'ai essayé GlobalKey, mais j'obtiens maintenant cette exception : 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
Il semble que vous utilisiez un GlobalKey
comme argument lorsqu'un BuildContext
est attendu. Je ne peux pas vous aider à déboguer davantage sans voir plus de votre code. Veuillez poster la ligne de code qui lève l'exception. Vous n'utilisez probablement pas les bons arguments.
Je peux confirmer qu'en utilisant le Builder
L'option que vous avez proposée fonctionne bien. J'ai rencontré ce problème et cela l'a résolu pour moi.
Pour afficher un message Toast, vous pouvez utiliser le plugin FlutterToast. Pour utiliser ce plugin, vous devez :
fluttertoast: ^3.1.0
$ flutter packages get
import 'package:fluttertoast/fluttertoast.dart';
Utilisez-le 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 ce .
Je voudrais proposer une solution alternative à l'utilisation du package barre de flottaison .
Comme le disait l'emballage : Utilisez ce paquet si vous avez besoin de plus de personnalisation lors de la notification de votre utilisateur. Pour les développeurs Android, il est fait pour remplacer les toasts et les snacks.
Une autre suggestion pour utiliser la flushbar est Comment puis-je afficher un snackbar après navigator.pop(context) 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);
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.