如何在Flutter中正确显示Snackbar? [英] How to properly display a Snackbar in Flutter?

查看:345
本文介绍了如何在Flutter中正确显示Snackbar?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在单击floatingActionbutton时显示Snackbar.但是,当我单击floatingactionbutton时,它什么都没有显示.这是我的代码.我正在使用StatefulWidget.我调试并检查了onPressed函数是否也正在执行,但是以某种方式Snackbar不可见.可能是此问题的根本原因是什么?我觉得我传递的BuildContext有问题.

I am trying to show a Snackbar on click of a floatingActionbutton. But when I click on the floatingactionbutton it's not showing anything. Here is my code. I am using a StatefulWidget. I debugged and checked that the onPressed function is also getting executed but somehow the Snackbar is not visible. What can be the root cause of the issue? I feel the BuildContext I am passing has some issue.

class MyApp extends StatefulWidget{
  @override
  MyAppState createState() {
    // TODO: implement createState
    return new MyAppState();
  }

}

class MyAppState extends State<MyApp>{
  File _image;
  String _text;

  Future getImage() async {
    var image = await ImagePicker.pickImage(source: ImageSource.camera);
    _image = image;
    final FirebaseVisionImage visionImage = FirebaseVisionImage.fromFile(_image);
    final TextRecognizer textRecognizer = FirebaseVision.instance.textRecognizer();
    final VisionText visionText = await textRecognizer.processImage(visionImage);

    String detectedText = visionText.text;

    setState(() {
      _image = image;
      _text = detectedText;
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: new AppBar(
          title: new Text('Image Picker Example'),
        ),
        body: new Center(
          child: _image == null
              ? new Text('No image selected.')
              : new Image.file(_image),
        ),
        floatingActionButton: new FloatingActionButton(
          onPressed: (){
            showSnackBar(context);
//            getImage();
          },
          tooltip: 'Pick Image',
          child: new Icon(Icons.add_a_photo),
        ),
      ),
    );
  }

  void showSnackBar(BuildContext context) {
    final scaffold = Scaffold.of(context);
    final snackBarContent = SnackBar(
      content: Text("sagar"),
      action: SnackBarAction(
          label: 'UNDO', onPressed: scaffold.hideCurrentSnackBar),
    );
    scaffold.showSnackBar(snackBarContent);
  }

}

推荐答案

之所以会发生这种情况,是因为所使用的BuildContext没有祖先,因此无法找到它来渲染SnackBar.直到显示Scaffold.

That happens because the BuildContext used has not a Scaffold ancestor thus, won't be able to find it to render a SnackBar since it's up to the Scaffold to display it.

根据方法文档:

在相同的构建函数中实际创建了脚手架时, 构建函数的上下文参数不能用于查找 脚手架(因为它在返回的小部件上方").在这样的 情况下,可以使用带有Builder的以下技术来提供 BuildContext位于支架"下方的新作用域:

When the Scaffold is actually created in the same build function, the context argument to the build function can't be used to find the Scaffold (since it's "above" the widget being returned). In such cases, the following technique with a Builder can be used to provide a new scope with a BuildContext that is "under" the Scaffold:

@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: () {
              Scaffold.of(context).showSnackBar(SnackBar(
                content: Text('Hello!'),
              ));
            },
          ),
        );
      },
    ),
  );
}

解决方案

FloatingActionButton包装在Builder小部件中,将比使用GlobalKey(通过@Epizon答案已经提到)更加优雅.

Wrapping your FloatingActionButton in a Builder widget will make it possible in a more elegant way than using a GlobalKey, which was already mentioned by the @Epizon answer.

这篇关于如何在Flutter中正确显示Snackbar?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆