如何在没有脚手架的情况下显示snackBar

Posted

技术标签:

【中文标题】如何在没有脚手架的情况下显示snackBar【英文标题】:How to show snackBar without Scaffold 【发布时间】:2019-12-07 13:55:49 【问题描述】:

我试图在我的应用程序中显示小吃栏以通知用户,但没有脚手架它会显示错误。我当前的代码是:

scaffoldKey.currentState?.showSnackBar(
    new SnackBar(
      backgroundColor: color ?? Colors.red,
      duration: Duration(milliseconds: milliseconds),
      content: Container(
        height: 50.0,
        child: Center(
          child: new Text(
            title,
            style: AppTheme.textStyle.lightText.copyWith(color: Colors.white),
            overflow: TextOverflow.ellipsis,
          ),
        ),
      ),
    ),
  )

【问题讨论】:

您可能还有一个包含Scaffold 的父小部件。为此创建一个scaffoldKey 并将其传递给您的孩子widget,该孩子必须显示Snakcbar。请注意,如果没有 Scaffold 小部件,您将无法使用 Sanckbar 我想在没有脚手架的情况下实现它。这可以实现吗? 不,没有Scaffold,你不能这样做。 【参考方案1】:

它可以像这样获取当前上下文并显示snackbar:

void _showToast(BuildContext context) 
  final scaffold = Scaffold.of(context);
  scaffold.showSnackBar(
    SnackBar(
      content: const Text('Updating..'),
    ),
  );


this._showToast(context);

【讨论】:

你不能在没有脚手架上下文的情况下显示snackbar。【参考方案2】:

如果您有权访问上下文,请从laszlo's answer 调用

ScaffoldMessenger.of(context).showSnackBar(snackBar);

如果您没有上下文(例如:显示网络请求错误),请根据Miguel Ruvio 的回答使用此 sn-p

我们将使用属性scaffoldMessengerKey,它允许我们在不需要上下文的情况下仅使用一个GlobalKey 来显示snackbars。此外,无需添加像 Get 这样的 3rd 方包。


首先,创建一个 globals.dart 来存储一个 GlobalKey

//globals.dart

import 'package:flutter/material.dart';

final GlobalKey<ScaffoldMessengerState> snackbarKey =
    GlobalKey<ScaffoldMessengerState>();

二、MaterialApp添加scaffoldMessengerKey属性

//main.dart

import 'globals.dart';

class MyApp extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return MaterialApp(
      title: 'Test',
      scaffoldMessengerKey: snackbarKey, // <= this
      ...

最后,在任何地方引用此键以显示 Snackbar

// anywhere

import 'globals.dart';

final SnackBar snackBar = SnackBar(content: Text("your snackbar message"));
snackbarKey.currentState?.showSnackBar(snackBar); 

【讨论】:

我认为这应该是公认的答案。如果您使用 Provider、MVVM 架构,并且出于任何原因,您想从 viewModel 中创建 Snackbars,则效果很好。【参考方案3】:

不,这是不可能的。 Snackbar 是 Scaffold 的一部分。 它必须有一个 Scaffold 父级。 Snackbar

在 Scaffold 父级中,您可以执行以下操作

BuildContext con=context;
final snackBar = SnackBar(content: Text(message));
Scaffold.of(con).showSnackBar(snackBar);

【讨论】:

【参考方案4】:

使用https://pub.dev/packages/get

然后你可以简单地调用 Get.snackbar() 来显示你希望它显示的位置。

Get.snackbar('Hi', 'i am a modern snackbar');

注意

你也可以在没有上下文的情况下使用这个包。

【讨论】:

【参考方案5】:

Scaffold.of(context).showSnackBar()弃用。您现在应该使用 ScaffoldMessenger。

例如:ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("Clicked!")));

Here 列出了新方法的好处。

【讨论】:

以上是关于如何在没有脚手架的情况下显示snackBar的主要内容,如果未能解决你的问题,请参考以下文章

如何从根祖先访问 Flutter 中最新的脚手架?

Flutter:为什么在构建函数中基于条件语句在脚手架之间进行切换,但不适用于自定义窗口小部件

在这种情况下,脚手架是啥意思?

将 EF Core 搭建到现有 DbContext 的脚手架

在使用vue脚手架时为啥不能加载favicon.ico图标

在 vaadin on grails 应用程序中启用脚手架