【问题标题】:How to properly display a Snackbar in Flutter?如何在 Flutter 中正确显示 Snackbar?
【发布时间】:2019-05-24 03:01:18
【问题描述】:

我试图在点击floatingActionbutton 时显示Snackbar。但是当我点击floatingactionbutton 时,它什么也没显示。这是我的代码。我正在使用StatefulWidget。我调试并检查了 onPressed 函数是否也在执行,但不知何故 Snackbar 不可见。问题的根本原因是什么?我觉得我传递的 BuildContext 有问题。

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);
  }

}

【问题讨论】:

    标签: flutter dart snackbar


    【解决方案1】:

    发生这种情况是因为使用的BuildContext 没有Scaffold 祖先,因此无法找到它来呈现SnackBar,因为它取决于Scaffold 来显示它。

    根据of method 文档:

    当 Scaffold 实际在同一个构建函数中创建时, 构建函数的上下文参数不能用于查找 脚手架(因为它在被返回的小部件“上方”)。在这样的 在这种情况下,可以使用以下带有 Builder 的技术来提供 具有位于脚手架“下方”的 BuildContext 的新范围:

    @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!'),
                  ));
                },
              ),
            );
          },
        ),
      );
    }
    

    解决方案

    将您的 FloatingActionButton 包装在 Builder 小部件中将比使用 @Epizon 答案中已经提到的 GlobalKey 更优雅。

    【讨论】:

      【解决方案2】:
      class MyApp extends StatefulWidget{
        @override
        MyAppState createState() {
          // TODO: implement createState
          return new MyAppState();
        }
      
      }
      
      class MyAppState extends State<MyApp>{
      
        final GlobalKey<ScaffoldState> _scaffoldkey = new GlobalKey<ScaffoldState>();
        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(
              key: _scaffoldkey,
              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();
      //            getImage();
                },
                tooltip: 'Pick Image',
                child: new Icon(Icons.add_a_photo),
              ),
            ),
          );
        }
      
        void showSnackBar() {
          final snackBarContent = SnackBar(
            content: Text("sagar"),
            action: SnackBarAction(
                label: 'UNDO', onPressed: _scaffoldkey.currentState.hideCurrentSnackBar),
          );
          _scaffoldkey.currentState.showSnackBar(snackBarContent);
        }
      
      
      
      }
      

      【讨论】:

        【解决方案3】:

        显示SnackBar你可以这样使用:

         ScaffoldMessenger.of(context).showSnackBar(SnackBar(
                  content: Text('User Logged In'),
                ));
        

        以前的SnackBar是这样使用的:

        Scaffold.of(context).showSnackBar(SnackBar(
                        content: Text('Rahul Kushwaha!'),
                      ));
        

        现在,SnackBar 由 ScaffoldMessenger 管理。有关详细信息,请研究此link

        【讨论】:

          【解决方案4】:

          在最新版本中--

          完整示例

          
          import 'package:flutter/material.dart';
          
          
          void test() {
            runApp(MyApp());
          }
          
          class MyApp extends StatelessWidget {
            // This widget is the root of your application.
            @override
            Widget build(BuildContext context) {
              return MaterialApp(
                title: 'Test App',
                theme: ThemeData(
                  primarySwatch: Colors.blue,
                  visualDensity: VisualDensity.adaptivePlatformDensity,
                ),
                home: testPage(title: 'Flutter Demo Home Page'),
              );
            }
          }
          
          class testPage extends StatefulWidget {
            testPage({Key? key, required this.title}) : super(key: key);
          
            final String title;
          
            @override
            _testPageState createState() => _testPageState();
          }
          
          class _testPageState extends State<testPage> {
          
            GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
          
            @override
            Widget build(BuildContext context) {
              return MaterialApp(
          
                  home: SizedBox(
                      child: Scaffold(
          
                          key: _scaffoldKey,
          
                          body: Center(
                              child: RaisedButton(
                                shape: RoundedRectangleBorder(
                                  borderRadius: BorderRadius.circular(10.0),
                                ),
                                onPressed: () {
          
                                  final snackBar = SnackBar(content: Text('Your Text'));
          
                                  _scaffoldKey.currentState!.showSnackBar(snackBar);
                                },
          
                                child: Text("Show SB"),
                              )
                          )
                      )
                  )
              );
            }
          }
          
          
            [1]: https://i.stack.imgur.com/hKQYZ.jpg
          

          【讨论】:

            猜你喜欢
            • 2020-09-24
            • 2019-08-28
            • 2017-03-27
            • 2019-07-27
            • 1970-01-01
            • 1970-01-01
            • 2019-12-15
            • 2019-04-16
            • 2021-01-19
            相关资源
            最近更新 更多