在Flutter中显示SnackBar

kos*_*cki 27 dart snackbar android-snackbar flutter

我想在Flutter的有状态小部件中显示一个简单的SnackBar.我的应用程序使用名为MyHomePage的有状态窗口小部件创建MaterialApp的新实例.

我尝试在showSnackBar()方法中显示SnackBar.但它失败的' 方法'showSnackBar'在null上被调用 '.

这段代码出了什么问题?

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key);

  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();

  @override
  void initState() {
    super.initState();
    showInSnackBar("Some text");
  }

  @override
  Widget build(BuildContext context) {
    return new Padding(
            key: _scaffoldKey,
            padding: const EdgeInsets.all(16.0),
            child: new Text("Simple Text")
    );
  }

  void showInSnackBar(String value) {
    _scaffoldKey.currentState.showSnackBar(new SnackBar(
        content: new Text(value)
    ));
  }
}
Run Code Online (Sandbox Code Playgroud)

解:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
        title: 'Flutter',
        theme: new ThemeData(
            primarySwatch: Colors.blue,
        ),
        home: new Scaffold(body: new MyHomePage()),
      );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key);

  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    showInSnackBar("Some text");
    return new Padding(
        padding: const EdgeInsets.all(16.0),
        child: new Scaffold(
          body: new Text("Simple Text")
        )
    );
  }

  void showInSnackBar(String value) {
    Scaffold.of(context).showSnackBar(new SnackBar(
        content: new Text(value)
    ));
  }
}
Run Code Online (Sandbox Code Playgroud)

Ian*_*son 30

有三个问题.首先是你没有任何地方的脚手架,而脚手架小部件是知道如何显示小吃店的人.第二个是你有一把钥匙可以抓住脚手架,但是你把它放在Padding上(Paddings对小吃店没有任何了解).第三个是你在与它相关联的小部件之前使用了密钥有机会被初始化,因为在构建之前调用了initState.

最简单的解决方案是将homeMyApp小部件中的行更改为:

home: new Scaffold(body: new MyHomePage()),

...然后删除所有提及,_scaffoldKey改为使用Scaffold.of(context)您目前所拥有的位置_scaffoldKey.currentState.


Jac*_*per 19

在我的情况下,我有这样的代码(在类状态)

final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();

void showInSnackBar(String value) {
    _scaffoldKey.currentState.showSnackBar(new SnackBar(content: new Text(value)));
}
Run Code Online (Sandbox Code Playgroud)

但我没有设置脚手架的钥匙.所以当我添加键:_scaffoldKey

 @override
 Widget build(BuildContext context) {
  return new Scaffold(
    key: _scaffoldKey,
    body: new SafeArea(
Run Code Online (Sandbox Code Playgroud)

snackbar开始工作:)

  • showSnackBar 方法未建立在 currentState 上 (2认同)

Cop*_*oad 12

ScaffoldState现在已弃用。使用ScaffoldMessengerState.

通常有两种显示SnackBarusing 的方式ScaffoldMessenger


  1. 直接方式:

    @override
    Widget build(BuildContext context) {
      return Scaffold(
        body: ElevatedButton(
          onPressed: () {
            var snackBar = SnackBar(content: Text('Hello World'));
            ScaffoldMessenger.of(context).showSnackBar(snackBar);
          },
          child: Text('Show SnackBar'),
        ),
      );
    }
    
    Run Code Online (Sandbox Code Playgroud)

  1. 使用GlobalKey.

    final _globalKey = GlobalKey<ScaffoldMessengerState>();
    
    @override
    Widget build(BuildContext context) {
      return ScaffoldMessenger(
        key: _globalKey,
        child: Scaffold(
          body: Center(
            child: ElevatedButton(
              onPressed: () {
                var snackBar = SnackBar(content: Text('Hello World'));
                _globalKey.currentState.showSnackBar(snackBar);
              },
              child: Text('Show SnackBar'),
            ),
          ),
        ),
      );
    }
    
    Run Code Online (Sandbox Code Playgroud)


小智 11

你可以使用这个:

final _scaffoldKey = GlobalKey<ScaffoldState>();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _scaffoldKey,
      appBar: AppBar(


    ),
  }
}
Run Code Online (Sandbox Code Playgroud)

然后在onPressed()可以添加此代码

_scaffoldKey.currentState.showSnackBar(
       new SnackBar(
          content: new Text('Hello this is snackbar!')
       )
);
Run Code Online (Sandbox Code Playgroud)


Wah*_*Haq 10

有一种更好更清洁的方式来显示颤动的Snackbar.我发现它很难分享,所以也许对其他人有帮助.

无需更改主应用程序部分

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
  return new MaterialApp(
    title: 'MyApp',
    theme: new ThemeData(
    primarySwatch: Colors.orange),
    home: new MainPage());
  }
}
Run Code Online (Sandbox Code Playgroud)

页面状态代码是事物发生变化的地方.

我们知道Flutter提供的Scaffold.of(context).showSnackBar.但是,上下文应该是脚手架后代的上下文,而不是包含脚手架的上下文.为了避免错误,我们需要为Scaffold的主体使用BuildContext,并将其存储在变量中,如下所示.

class MainPageState extends State<MainPage> {                                                                         
BuildContext scaffoldContext;                                                                                                                                                                                                

@override                                                                                                           
Widget build(BuildContext context) {                                                                                

return new Scaffold(                                                                                              
    backgroundColor: Colors.grey,                                                                                 
    appBar: new AppBar(                                                                                           
      title: const Text(APP_TITLE),                                                                               
    ),                                                                                                             
    body: new Builder(builder: (BuildContext context) {                                                           
      scaffoldContext = context;                                                                                  
      return new Center(
           child: new Text('Hello World', style: new TextStyle(fontSize: 32.0)),
         );                                                                                
    }));                                                                                                           
}                                                                                                                   


void createSnackBar(String message) {                                                                               
  final snackBar = new SnackBar(content: new Text(message),                                                         
  backgroundColor: Colors.red);                                                                                      

  // Find the Scaffold in the Widget tree and use it to show a SnackBar!                                            
  Scaffold.of(scaffoldContext).showSnackBar(snackBar);                                                              
  }                                                                                                                   
}     
Run Code Online (Sandbox Code Playgroud)

现在,您可以从任何地方调用此函数,它将显示Snackbar.例如,我用它来显示Internet连接消息.


Sye*_*med 8

要在 initState() 上初始化 Snackbar,您可以在构建布局后执行一个函数。

void initState() {
super.initState();
WidgetsBinding.instance
    .addPostFrameCallback((_) => _scaffoldKey.currentState.showSnackBar(SnackBar(content: Text("Your message here..")));}
Run Code Online (Sandbox Code Playgroud)


yub*_*del 8

Scaffold.of(context).showSnackBar(
     SnackBar(content: Text("Thanks for using snackbar",
     textAlign: TextAlign.center, style: TextStyle(fontSize: 16.0, fontWeight: 
     FontWeight.bold),), duration: Duration(seconds: 2), backgroundColor: Colors.red,)
);
Run Code Online (Sandbox Code Playgroud)


far*_*ora 6

Scaffold.Of(context)不推荐用于显示小吃栏。

使用新方法:

final snackBar = SnackBar(content: Text('Yay! A SnackBar!'));

ScaffoldMessenger.of(context).showSnackBar(snackBar);
Run Code Online (Sandbox Code Playgroud)

snackbars


Ale*_*uin 5

initState之前被调用过,build我猜_scaffoldKey.currentState在调用时还没有初始化。

我不知道你是否能得到一个ScaffoldStateinitState。如果您更改代码,您可以使用以下build方法显示小吃店:

Scaffold.of(context).showSnackBar(SnackBar(Text(value)));
Run Code Online (Sandbox Code Playgroud)


小智 5

我把它弄干净,为我工作:)

@override
Widget build(BuildContext context) {
  return new Scaffold(
    appBar: new AppBar(
      title: new Text('Demo')
    ),
    body: new Builder(
      // Create an inner BuildContext so that the onPressed methods
      // can refer to the Scaffold with Scaffold.of().
      builder: (BuildContext context) {
        return new Center(
          child: new RaisedButton(
            child: new Text('SHOW A SNACKBAR'),
            onPressed: () {
              Scaffold.of(context).showSnackBar(new SnackBar(
                content: new Text('Hello!'),
              ));
            },
          ),
        );
      },
    ),
  );
}
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

30053 次

最近记录:

6 年,5 月 前