首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用不包含Scaffold的上下文调用Scaffold.of()

使用不包含Scaffold的上下文调用Scaffold.of()
EN

Stack Overflow用户
提问于 2018-07-12 11:32:10
回答 13查看 132.2K关注 0票数 341

正如你所看到的,我的按钮在Scaffold的身体里。但是我得到了这个例外:

使用不包含Scaffold的上下文调用Scaffold.of()。

代码语言:javascript
复制
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

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

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('SnackBar Playground'),
      ),
      body: Center(
        child: RaisedButton(
          color: Colors.pink,
          textColor: Colors.white,
          onPressed: _displaySnackBar(context),
          child: Text('Display SnackBar'),
        ),
      ),
    );
  }
}

_displaySnackBar(BuildContext context) {
  final snackBar = SnackBar(content: Text('Are you talkin\' to me?'));
  Scaffold.of(context).showSnackBar(snackBar);
}

编辑:

我找到了另一个解决这个问题的方法。如果我们给Scaffold一个键,即GlobalKey<ScaffoldState>,我们可以按下面的方式显示SnackBar,而不需要将我们的身体封装在Builder小部件中。不过,返回Scaffold的小部件应该是一个状态小部件。

代码语言:javascript
复制
 _scaffoldKey.currentState.showSnackBar(snackbar); 
EN

回答 13

Stack Overflow用户

回答已采纳

发布于 2018-07-12 11:40:25

之所以会出现此异常,是因为您使用的是实例化context的小部件的Scaffold。不是context的一个孩子的Scaffold

您可以通过使用不同的上下文来解决这个问题:

代码语言:javascript
复制
Scaffold(
    appBar: AppBar(
        title: Text('SnackBar Playground'),
    ),
    body: Builder(
        builder: (context) => 
            Center(
            child: RaisedButton(
            color: Colors.pink,
            textColor: Colors.white,
            onPressed: () => _displaySnackBar(context),
            child: Text('Display SnackBar'),
            ),
        ),
    ),
);

注意,虽然我们在这里使用Builder,但这并不是获得不同BuildContext的唯一方法。

还可以将子树提取到不同的Widget中(通常使用extract widget重构)。

票数 445
EN

Stack Overflow用户

发布于 2018-12-21 18:04:47

您可以使用GlobalKey。唯一的缺点是使用GlobalKey可能不是最有效的方法。

这方面的一个好处是,您还可以将此键传递给其他不包含任何脚手架的定制小部件类。见(这里)

代码语言:javascript
复制
class HomePage extends StatelessWidget {
  final _scaffoldKey = GlobalKey<ScaffoldState>(); \\ new line
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _scaffoldKey,                           \\ new line
      appBar: AppBar(
        title: Text('SnackBar Playground'),
      ),
      body: Center(
        child: RaisedButton(
          color: Colors.pink,
          textColor: Colors.white,
          onPressed: _displaySnackBar(context),
          child: Text('Display SnackBar'),
        ),
      ),
    );
  }
  _displaySnackBar(BuildContext context) {
    final snackBar = SnackBar(content: Text('Are you talkin\' to me?'));
    _scaffoldKey.currentState.showSnackBar(snackBar);   \\ edited line
  }
}
票数 186
EN

Stack Overflow用户

发布于 2019-05-01 10:57:00

更新- 2021

Scaffold.of(context)被反对为ScaffoldMessenger

请从方法的文档中检查这一点:

ScaffoldMessenger现在处理SnackBars,以便在各路由之间持久化,并且始终显示在当前Scaffold上。默认情况下,根ScaffoldMessenger包含在MaterialApp,中,但您可以为ScaffoldMessenger创建自己的受控范围,以进一步控制哪些脚手架接收SnackBars。

代码语言:javascript
复制
@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
      title: Text('Demo')
    ),
    body: Builder(
      // Create an inner BuildContext so that the onPressed methods
      // can refer to the Scaffold with Scaffold.of().
      builder: (BuildContext context) {
         return Center(
          child: RaisedButton(
            child: Text('SHOW A SNACKBAR'),
            onPressed: () {
              ScaffoldMessenger.of(context).showSnackBar(SnackBar(
                content: Text('Hello!'),
              ));
            },
          ),
        );
      },
    ),
  );
}

您可以检查详细的弃用和新方法这里

票数 32
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51304568

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档