Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/flutter/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Flutter 使用不包含脚手架的上下文调用Scaffold.of()_Flutter_Scaffold_Snackbar - Fatal编程技术网

Flutter 使用不包含脚手架的上下文调用Scaffold.of()

Flutter 使用不包含脚手架的上下文调用Scaffold.of(),flutter,scaffold,snackbar,Flutter,Scaffold,Snackbar,如您所见,我的按钮位于脚手架的主体内。但我有一个例外: 使用不包含脚手架的上下文调用Scaffold.of() 编辑: 我找到了解决这个问题的另一个办法。如果我们给Scaffold一个键,即GlobalKey,我们可以如下显示SnackBar,而无需将我们的身体包裹在Builder小部件中。返回Scaffold的小部件应该是有状态的小部件 _scaffoldKey.currentState.showSnackBar(snackbar); 发生此异常是因为您正在使用实例化了Scaffold的

如您所见,我的按钮位于
脚手架的主体内。但我有一个例外:

使用不包含脚手架的上下文调用Scaffold.of()

编辑:

我找到了解决这个问题的另一个办法。如果我们给
Scaffold
一个键,即
GlobalKey
,我们可以如下显示SnackBar,而无需将我们的身体包裹在
Builder
小部件中。返回
Scaffold
的小部件应该是有状态的小部件

 _scaffoldKey.currentState.showSnackBar(snackbar); 

发生此异常是因为您正在使用实例化了
Scaffold
的小部件的
上下文。不是
Scaffold
的子对象的
上下文

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

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
的唯一方法

还可以将子树提取到不同的
小部件
(通常使用
提取小部件
重构)

使用
脚手架信使
(推荐)
var snackBar=snackBar(内容:Text('Hi there');
ScaffoldMessenger.of(上下文)。showSnackBar(snackBar);

示例(不带
Builder
GlobalKey
脚手架(
主体:升降按钮(
已按下:(){
var snackBar=snackBar(内容:Text('Hello World'));
ScaffoldMessenger.of(上下文)。showSnackBar(snackBar);
},
子项:文本('Show SnackBar'),
),
)

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

这样做的一个好处是,您还可以将该键传递给其他不包含任何脚手架的自定义小部件类。见()

类主页扩展了无状态小部件{
最终的_scaffoldKey=GlobalKey();\\新行
@凌驾
小部件构建(构建上下文){
返回脚手架(
钥匙:脚手架钥匙\\新品
appBar:appBar(
标题:文本(“SnackBar游乐场”),
),
正文:中(
孩子:升起按钮(
颜色:颜色。粉红色,
textColor:Colors.white,
按下时:_显示快捷键(上下文),
子项:文本(“显示快捷键”),
),
),
);
}
_displaySnackBar(构建上下文){
final snackBar=snackBar(内容:Text(“你在跟我说话吗?”);
_scaffoldKey.currentState.showSnackBar(snackBar);\编辑行
}
}
更新-2021年
Scaffold.of(context)
被弃用,取而代之的是
ScaffoldMessenger

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

ScaffoldMessenger现在处理snackbar,以便在整个应用程序中保持一致 路线和路线始终显示在当前脚手架上。默认情况下 rootScaffoldMessenger包含在材质应用中,但您可以 为脚手架Messenger创建您自己的控制范围,以进一步 控制哪些脚手架可以放置你的蛇杠

@覆盖
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(
标题:文本(“演示”)
),
车身:建造商(
//创建内部BuildContext,以便onPressed方法
//可以使用Scaffold.of()引用脚手架。
生成器:(BuildContext上下文){
返回中心(
孩子:升起按钮(
子项:文本(“显示快捷键”),
已按下:(){
ScaffoldMessenger.of(上下文)。showSnackBar(SnackBar(
内容:Text('Hello!'),
));
},
),
);
},
),
);
}

您可以查看详细的反对意见和新方法:

解决此问题的简单方法是使用以下代码为您的脚手架创建一个最终密钥:

第一个:
GlobalKey()\u scaffoldKey=GlobalKey
();

第二步:为脚手架分配钥匙
Key:\u scaffoldKey

第三:使用
\u scaffoldKey.currentState.showSnackBar(SnackBar(内容:文本(“欢迎”))

您可以通过两种方式解决此问题:

1)使用生成器小部件

Scaffold(
    appBar: AppBar(
        title: Text('My Profile'),
    ),
    body: Builder(
        builder: (ctx) => RaisedButton(
            textColor: Colors.red,
            child: Text('Submit'),
            onPressed: () {
                 Scaffold.of(ctx).showSnackBar(SnackBar(content: Text('Profile Save'),),);
            }               
        ),
    ),
);
2)使用GlobalKey

class HomePage extends StatelessWidget {
  
  final globalKey = GlobalKey<ScaffoldState>();
  
  @override
  Widget build(BuildContext context) {
     return Scaffold(
       key: globalKey,
       appBar: AppBar(
          title: Text('My Profile'),
       ),
       body:  RaisedButton(
          textColor: Colors.red,
          child: Text('Submit'),
          onPressed: (){
               final snackBar = SnackBar(content: Text('Profile saved'));
               globalKey.currentState.showSnackBar(snackBar);
          },
        ),
     );
   }
}
类主页扩展了无状态小部件{
最终globalKey=globalKey();
@凌驾
小部件构建(构建上下文){
返回脚手架(
关键:环球银行,
appBar:appBar(
标题:文本(“我的个人资料”),
),
主体:升起按钮(
textColor:Colors.red,
子项:文本('Submit'),
已按下:(){
最终snackBar=snackBar(内容:文本(“已保存配置文件”);
globalKey.currentState.showSnackBar(snackBar);
},
),
);
}
}

一个更有效的解决方案是将构建函数拆分为几个小部件。 这将引入一个“新上下文”,您可以从中获得Scaffold

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Scaffold.of example.')),
        body: MyScaffoldBody(),
      ),
    );
  }
}

class MyScaffoldBody extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: RaisedButton(
          child: Text('Show a snackBar'),
          onPressed: () {
            Scaffold.of(context).showSnackBar(
              SnackBar(
                content: Text('Have a Snack'),
              ),
            );
          }),
    );
  }
}
更新03.03.2021:颤振2.0刚刚发布。。。 (出于历史价值考虑,我还让您进一步了解我的原始答案…)


现在。。。输入…

从我们读到的

脚手架中的SnackBar API现在由ScaffoldMessenger处理,其中一个默认情况下在MaterialApp上下文中可用

因此,使用全新的ScaffoldMessenger现在您可以编写如下代码

脚手架(
钥匙:脚手架钥匙,
正文:手势检测器(
onTap:(){
ScaffoldMessenger.of(上下文)。showSnackBar(SnackBar(
内容:常量文本(“零食”),
持续时间:常数持续时间(秒数:1),
行动:SnackBarAction(
标签:“行动”,
按下:(){},
),
));
},
子项:常量文本('SHOW SNACK'),
),
);
class HomePage extends StatelessWidget {
  
  final globalKey = GlobalKey<ScaffoldState>();
  
  @override
  Widget build(BuildContext context) {
     return Scaffold(
       key: globalKey,
       appBar: AppBar(
          title: Text('My Profile'),
       ),
       body:  RaisedButton(
          textColor: Colors.red,
          child: Text('Submit'),
          onPressed: (){
               final snackBar = SnackBar(content: Text('Profile saved'));
               globalKey.currentState.showSnackBar(snackBar);
          },
        ),
     );
   }
}
void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Scaffold.of example.')),
        body: MyScaffoldBody(),
      ),
    );
  }
}

class MyScaffoldBody extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: RaisedButton(
          child: Text('Show a snackBar'),
          onPressed: () {
            Scaffold.of(context).showSnackBar(
              SnackBar(
                content: Text('Have a Snack'),
              ),
            );
          }),
    );
  }
}
Flushbar(
                  title:  "Hey Ninja",
                  message:  "Lorem Ipsum is simply dummy text of the printing and typesetting industry",
                  duration:  Duration(seconds: 3),              
                )..show(context);
Singleton.showInSnackBar(
    Scaffold.of(context).context, "Theme Changed Successfully");
// Just use Scaffold.of(context) before context!!
return Scaffold(
  key: _scaffoldKey, //this is the key
  endDrawer: Drawer(),
  appBar: AppBar( 
//all codes for appbar here
actions: [
IconButton(
        splashRadius: 20,
        icon: Icon(Icons.settings),
        onPressed: () {
          _scaffoldKey.currentState.openEndDrawer(); // this is it
       
        },
      ),]
           Expanded(
              child: Container(
                width: MediaQuery.of(context).size.width,
                height: MediaQuery.of(context).size.height,
                child: Builder(
                  builder: (context) => RaisedButton(
                    onPressed: () {
                        final snackBar = SnackBar(
                          content: Text("added to cart"),
                           action: SnackBarAction(
                            label: 'Undo',
                             onPressed: () {
                              // Some code to undo the change.
                            },
                          ),
                        );
                    },
                    textColor: Colors.white,
                    color: Colors.pinkAccent,
                    child: Text("Add To Cart",
                        style: TextStyle(
                            fontSize: 18, fontWeight: FontWeight.w600)),
                  ),
                ),
              ),
            )
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("SnackBar Message")));