如何在Flutter中创建Toast?

azi*_*iza 106 flutter

我可以在Flutter中创建类似于Toasts的东西吗?只是一个微小的通知窗口,它不直接面向用户,并且不会锁定或淡化其背后的视图?

Rém*_*let 127

您可以访问父ScaffoldState使用Scaffold.of(context)

然后做类似的事情

Scaffold.of(context).showSnackBar(SnackBar(
      content: Text("Sending Message"),
    ));
Run Code Online (Sandbox Code Playgroud)

Snackbars是材料设计的官方"吐司".请参阅https://material.io/design/components/snackbars.html#usage

这是一个完整的例子:

在此输入图像描述

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),
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 例如,这应该如何包装在 onPressed 中?因为我试过了,屏幕上什么也没有显示。 (3认同)
  • 调用“showSnackBar()”的小部件应该有一个“Scaffold”父级。 (2认同)
  • 注意:如果您正在使用答案中提到的 Snackbar 解决方案,并且想要更接近传统 Android Toast 视图,请在 Snackbar 中使用浮动行为,例如 ->“行为:SnackBarBehavior.floating”。它将 Snackbar 从底部分离,您将得到更接近传统吐司的东西。 (2认同)
  • 收到错误 -“showSnackBar”已弃用,不应使用。使用 ScaffoldMessenger.showSnackBar。此功能在 v1.23.0-14.0.pre 之后已被弃用。尝试用替换成员替换已弃用成员的使用。 (2认同)
  • 现在已弃用!新版本是“ScaffoldMessage.showSnackBar()”。 (2认同)

Col*_*son 56

SnackBar 正如Darky所指出的,它绝对是正确使用的类.

小吃店

一个棘手的问题showSnackBarScaffoldState,如果你试图showSnackBar在你构建你的构建方法中调用它Scaffold.

您可能会看到这样的错误,其中包含一些解释如何解决问题的文本.

??? 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)
????????????????????????????????????????????????????????????????????????????????????????????????????
Run Code Online (Sandbox Code Playgroud)

你可以传递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),
          );
        }
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

或者您可以使用a Builder来创建一个BuildContextScaffold的孩子.

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),
          );
        }
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

最后,您可以将窗口小部件拆分为多个类,这是最好的长期方法.

  • 我可以确认使用您提供的`Builder` 选项效果很好。遇到了这个问题,这为我解决了。 (2认同)

Rao*_*che 50

使用这个插件

Fluttertoast.showToast(
        msg: "This is Toast messaget",
        toastLength: Toast.LENGTH_SHORT,
        gravity: ToastGravity.CENTER,
        timeInSecForIos: 1
    );
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

  • 您必须首先在 pubspec.yaml 文件中添加 Fluttertoast 依赖项。依赖项的链接在这里 [link] (https://pub.dartlang.org/packages/fluttertoast)。然后就可以使用上面的代码 (3认同)
  • `未处理的异常:MissingPluginException(在通道 PonnamKarthik/fluttertoast 上未找到方法 showToast 的实现)` (2认同)
  • 现在它可以工作了,我需要停止应用程序并运行 ‍♂️ 而不进行调试:) (2认同)

Mic*_*cer 15

小吃店

当我尝试使用使用该ScaffoldState对象的解决方案(其他人建议的)时,我收到一条警告,指出它已被弃用

“showSnackBar”已弃用,不应使用。使用 ScaffoldMessenger.showSnackBar。此功能在 v1.23.0-14.0.pre 之后已弃用。

ScaffoldMessenger按预期使用作品:

ScaffoldMessenger.of(context)
    .showSnackBar(SnackBar(content: Text("My amazing message! O.o")));
Run Code Online (Sandbox Code Playgroud)

例子:

小吃店留言


fuc*_*kur 14

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
    );
Run Code Online (Sandbox Code Playgroud)

  • 请尝试添加一两个描述性句子来描述在哪里放置哪些代码。类似于“将包添加到您的 pubspec”和“在代码中,使用:” (3认同)

Vir*_*rma 9

要显示吐司消息,您可以使用flutterToast插件来使用此插件,

  1. 将此依赖项添加到您的pubspec.yaml文件中: fluttertoast: ^3.1.0
  2. 要获取软件包,您必须运行以下命令:- $ flutter packages get
  3. 导入包:- 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');
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请检查

  • 与其回答别人发布的相同答案,不如对他的答案进行投票。 (11认同)

Wal*_*ale 8

如果目前给出的 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。


chu*_*han 7

我想提供一个替代解决方案来使用包flushbar

正如软件包所说:如果您在通知用户时需要更多自定义,请使用此软件包。对于 Android 开发人员来说,它是用来替代吐司和小吃店的。

另一个使用flushbar的建议是如何在Flutter中的navigator.pop(context)之后显示snackbar?

您还可以将 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);
Run Code Online (Sandbox Code Playgroud)


小智 6

导入库 fluttertoast:3.1.3

像下面这样使用它:

Fluttertoast.showToast(
    msg: "Hello, World!",
    textColor: Colors.white,
    toastLength: Toast.LENGTH_SHORT,
    timeInSecForIos: 1,
    gravity: ToastGravity.BOTTOM,
    backgroundColor: Colors.indigo,
);
Run Code Online (Sandbox Code Playgroud)


Dha*_*ara 5

对于 Flutter 中的 toast 消息,使用bot_toast库。这个库提供了丰富的功能,支持显示通知、文本、加载、附件等。 Toast

在此处输入图片说明


Zak*_*han 5

在 Flutter 应用程序中显示 toast 的三种方式。

我会告诉你我所知道的所有三种方式,并选择你想使用的一种。我会推荐第二个。

1:使用外包装。

这是第一种方法,也是在 Flutter 应用程序中显示 toast 的最简单方法。

首先,您必须将此包添加到文件pubspec.YAML 中

flutter_just_toast:^version_here
Run Code Online (Sandbox Code Playgroud)

然后在要显示吐司的文件中导入包。

'package:flutter_just_toast/flutter_just_toast.dart';
Run Code Online (Sandbox Code Playgroud)

最后一步显示吐司。

Toast.show(message: "Your toast message",
           duration: Delay.SHORT,
           textColor: Colors.black);
Run Code Online (Sandbox Code Playgroud)

2:使用官方方式。

这个方法也很简单,但是你要处理它。我并不是说这很难,它简单而干净,我会推荐这种方法。

对于这种方法,您只需使用以下代码即可显示吐司。

Scaffold.of(context).showSnackBar(SnackBar(
          content: Text("Sending Message"),
        ));
Run Code Online (Sandbox Code Playgroud)

但请记住,您必须使用脚手架上下文。

3:使用原生API。

现在,当您已经拥有上述两种方法时,此方法不再有意义。使用这种方法,您必须为 Android 和 iOS 编写本机代码,然后将其转换为插件,您就可以开始使用了。

这种方法会消耗你的时间,你必须重新发明轮子。这已经被发明了。