Odpowiedzi:
Możesz uzyskać dostęp do rodzica ScaffoldState
za pomocąScaffold.of(context)
Następnie zrób coś takiego
Scaffold.of(context).showSnackBar(SnackBar(
content: Text("Sending Message"),
));
Snackbary to oficjalny „Toast” z Material Design. Zobacz https://material.io/design/components/snackbars.html#usage
Oto w pełni działający przykład:
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),
),
);
}
}
showSnackBar()
powinno mieć Scaffold
rodzica.
Użyj tej wtyczki
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
jest zdecydowanie właściwą klasą do użycia, jak zauważył Darky.
Jedną trudną rzeczą showSnackBar
jest dotarcie do ScaffoldState
, jeśli próbujesz wywołać showSnackBar
w ramach metody kompilacji, w której konstruujesz plik Scaffold
.
Możesz zobaczyć taki błąd, który zawiera tekst wyjaśniający, jak rozwiązać problem.
══╡ 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)
════════════════════════════════════════════════════════════════════════════════════════════════════
Można też przekazać GlobalKey
do Scaffold
konstruktora:
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),
);
}
),
);
}
}
Lub możesz użyć a, Builder
aby utworzyć BuildContext
element podrzędny Rusztowania.
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),
);
}
),
);
}
}
Wreszcie, możesz podzielić swój widget na wiele klas, co jest najlepszym podejściem długoterminowym.
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
jako argumentu, w którym BuildContext
oczekuje się a. Nie mogę pomóc w dalszym debugowaniu tego problemu bez przeglądania większej ilości kodu. Opublikuj wiersz kodu, który zgłasza wyjątek, prawdopodobnie po prostu nie używasz właściwych argumentów.
Builder
podanej przez Ciebie opcji działa dobrze. Wpadłem na ten problem i to rozwiązało go dla mnie.
final key = new GlobalKey<ScaffoldState>();
poza kompilację Widgetu naprawiło go.
aby wyświetlić komunikat toast, możesz użyć wtyczki flutterToast, aby użyć tej wtyczki, którą musisz
fluttertoast: ^3.1.0
$ flutter packages get
import 'package:fluttertoast/fluttertoast.dart';
użyj tego w ten sposób
Fluttertoast.showToast(
msg: "your message",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM // also possible "TOP" and "CENTER"
backgroundColor: "#e74c3c",
textColor: '#ffffff');
Aby uzyskać więcej informacji, sprawdź to
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
);
Chciałbym przedstawić alternatywne rozwiązanie do korzystania z pakietu flushbar.
https://github.com/AndreHaueisen/flushbar
Jak wspomniano w pakiecie: Użyj tego pakietu, jeśli potrzebujesz więcej dostosowań podczas powiadamiania użytkownika. Dla programistów Androida ma zastąpić tosty i batoniki.
Kolejna sugestia użycia flushbar Jak wyświetlić snackbar po navigator.pop (kontekst) we Flutterze?
Możesz również ustawić pozycję flushbarPosition na TOP lub 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);
Zaimportuj plik lib
fluttertoast: 3.1.3
Użyj jak poniżej
Fluttertoast.showToast(
msg: "Hello world",
textColor: Colors.white,
toastLength: Toast.LENGTH_SHORT,
timeInSecForIos: 1,
gravity: ToastGravity.BOTTOM,
backgroundColor: Colors.indigo,
);
Na wypadek, gdyby podany dotychczas pakiet Fluttertoast nie działał ... W takim razie zasugeruję, abyś spróbował toast .
Bez fanaberii i bez ceremonii.
Po prostu działa.
Zauważyłem jednak błąd w przykładzie podanym w pliku Readme:
Toast.show("Toast plugin app", duration: Toast.LENGTH_SHORT, gravity: Toast.BOTTOM);
Chociaż metoda wymaga kontekstu. Warto więc dodać `` kontekst '' w następujący sposób:
Toast.show("Toast plugin app", context, duration: Toast.LENGTH_SHORT, gravity: Toast.BOTTOM);
Jest szansa, że zostanie to naprawione do czasu, gdy sprawdzałeś, chociaż przesłałem już PR.
pub.dartlang.org/packages/fluttertoast
wtyczki. Ten jest dużo bardziej przejrzysty [zwięzły] i łatwiejszy do dostosowania.
Istnieją trzy sposoby wyświetlania tostów w aplikacji flutter.
Opowiem ci o wszystkich trzech znanych mi sposobach i wybierzesz, z którego chcesz skorzystać. Poleciłbym drugą.
1: korzystanie z pakietu zewnętrznego.
jest to pierwsza metoda, która jest najłatwiejszym sposobem pokazania tostów w aplikacji flutter.
przede wszystkim musisz dodać ten pakiet w pubspec.yaml
flutter_just_toast:^version_here
następnie zaimportuj pakiet do pliku, w którym chcesz wyświetlić toast.
'package:flutter_just_toast/flutter_just_toast.dart';
i ostatni krok pokaż toast.
Toast.show( message: "Your toast message",
duration: Delay.SHORT,
textColor: Colors.black);
2: używając oficjalnego sposobu.
ta metoda jest również prosta, ale musisz sobie z nią poradzić. Nie mówię, że to jest trudne, jest proste i czyste. Poleciłbym tę metodę.
dla tej metody wszystko, co musisz zrobić, to pokazać toast, używając poniższego kodu.
Scaffold.of(context).showSnackBar(SnackBar(
content: Text("Sending Message"),
));
ale pamiętaj, że musisz użyć kontekstu rusztowania.
3: przy użyciu natywnego interfejsu API.
teraz ta metoda nie ma już sensu, jeśli masz już dwie powyższe metody. używając tej metody musisz napisać natywny kod dla Androida i iOS, a następnie przekonwertować go na wtyczkę i jesteś gotowy do pracy. ta metoda pochłonie Twój czas i musisz na nowo wynaleźć koło. który został już wynaleziony.
Dla tych, którzy szukają Toast
czegoś, co przetrwa zmianę trasy, SnackBar
może to nie być najlepsza opcja.
Overlay
Zamiast tego spójrz na .
Dodaj flutter_just_toast do swoich zależności w swoim Pubspecs.yaml
zależności:
flutter_just_toast: ^1.0.1
Następnie zaimportuj pakiet do swojej klasy:
import 'package:flutter_just_toast/flutter_just_toast.dart';
Zaimplementuj Toast z komunikatem
Toast.show( message: "Your toast message",
duration: Delay.SHORT,
textColor: Colors.black);
po prostu użyj SnackBar (content: Text ("hello"),) wewnątrz dowolnego wydarzenia, takiego jak onTap i onPress
możesz przeczytać więcej o Snackbar tutaj https://flutter.dev/docs/cookbook/design/snackbars
W tym celu istnieją różne wersje.
1) Przede wszystkim możesz użyć SnackBar, który jest widżetem we Flutterze.
2) Możesz korzystać z bibliotek takich jak toast, flutter_toast z pub.dev.
3) Trzecia wersja tworzy Twój niestandardowy widżet. Można go utworzyć za pomocą widżetu Nakładka i Animacji w aplikacji Flutter.
Możesz skorzystać z tego samouczka, aby dowiedzieć się więcej na ten temat. Oto link
W przypadku tostów z oryginalną grafiką na Androida możesz użyć tego: https://pub.dartlang.org/packages/fluttertoast
Działa dobrze na Androidzie i iOS. wprowadź opis obrazu tutaj
https://pub.dev/packages/toast użyj tego do tostów ta biblioteka jest dość łatwa w użyciu i doskonale działa na iOS i Android,
Składnia show Toast:
Toast.show("Toast plugin app", duration: Toast.LENGTH_SHORT, gravity: Toast.BOTTOM);
możesz użyć tego pakietu: toast
toast: ^0.1.5
import 'package:toast/toast.dart';
Toast.show("Toast plugin app", context, duration: Toast.LENGTH_SHORT, gravity: Toast.BOTTOM);
pobierz trzepotliwy pakiet tostów tutaj
Dodaj ten pakiet do zależności projektu w pubspec.yaml
Wtedy, gdy chcesz, aby Toast był wyświetlany jak po dotknięciu przycisku
Toast.show("Toast plugin app", context, duration: Toast.LENGTH_SHORT, gravity: Toast.BOTTOM);
Nie ma widżetu do tostów w trzepotaniu, możesz przejść do tej wtyczki Przykład zastosowania:
Fluttertoast.showToast(
msg: "My toast messge",
textColor: Colors.white,
toastLength: Toast.LENGTH_SHORT,
timeInSecForIos: 1,
gravity: ToastGravity.BOTTOM,
backgroundColor: Colors.indigo,);
Możesz użyć biblioteki „fluttertoast”. Aby to zrobić, dodaj go do pliku pubspec.yaml, na przykład:
dependencies:
fluttertoast: ^3.1.0
Następnie zaimportuj tę bibliotekę do pliku rzutek, którego potrzebujesz, i napisz swój kod. Na przykład odwołaj się do następującego kodu:
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());
Zaimportuj cupertino_icons: ^0.1.2
i napisz poniższy kod
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();
},
)
],
);
});
To całkiem proste,
Musimy tylko zainstalować pakiet tostów flutter. Zapoznaj się z następującą dokumentacją: https://pub.dev/packages/fluttertoast
W zakładce instalacji otrzymasz zależność, którą musisz wkleić do pliku pubspec.yaml, a następnie zainstalować.
Następnie wystarczy zaimportować pakiet:
import 'package: fluttertoast / fluttertoast.dart';
Podobnie jak w powyższej linii.
A następnie, używając klasy FlutterToast, możesz użyć swojego fluttertoast.
Jesteś skończony!!!
Możesz użyć czegoś takiego jak FlutterToast
Zaimportuj plik lib
fluttertoast: ^2.1.4
Użyj jak poniżej
Fluttertoast.showToast(
msg: "Hello world",
textColor: Colors.white,
toastLength: Toast.LENGTH_SHORT,
timeInSecForIos: 1,
gravity: ToastGravity.BOTTOM,
backgroundColor: Colors.indigo,
);
Otóż to..