【问题标题】:Snackbar on RaisedButton click in Flutter is not working? [duplicate]Flutter 中 RaisedButton 单击上的 Snackbar 不起作用? [复制]
【发布时间】:2020-12-14 08:36:35
【问题描述】:

我是 Flutter 的新手,我正在创建我的登录屏幕,并且我想在屏幕上显示一个 Snackbar,以防 OnPress of Raised Button,但我无法向我的应用程序显示此消息。如何解决这个问题。 我还附上了下面的错误描述以了解主要内容,我不知道如何管理它。 我使用 Material Button 和 Flat Button 而不是 Raised Button,但问题没有解决。 图片

代码

import 'package:flutter/material.dart';
import 'package:flutter_hello/Signup.dart';

main() {
  runApp(MaterialApp(
    // theme: ThemeData(primarySwatch: Colors.red, brightness: Brightness.light),
    title: "Umar",
    home: new Login(),
  ));
}

class Login extends StatefulWidget {
  @override
  _LoginState createState() => _LoginState();
}

class _LoginState extends State<Login> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        padding: EdgeInsets.all(28),
        child: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: [
              FlutterLogo(
                size: 150,
                colors: Colors.red,
              ),
              TextFormField(
                obscureText: false,
                // keyboardType: TextInputType.number,
                decoration: InputDecoration(
                  prefixIcon: Icon(Icons.person, color: Colors.grey),
                  hintText: 'Email',
                  contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
                ),
              ),
              TextFormField(
                obscureText: true,
                obscuringCharacter: "*",
                decoration: InputDecoration(
                  prefixIcon: Icon(Icons.lock_outline, color: Colors.grey),
                  hintText: 'Password',
                  contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
                ),
              ),
              RaisedButton(
                shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(18.0),
                    side: BorderSide(color: Colors.red)),
                color: Colors.red,
                textColor: Colors.white,
                padding: EdgeInsets.fromLTRB(40, 8, 40, 8),
                onPressed: () {
                  Scaffold.of(context).showSnackBar(SnackBar(
                    content: Text("Sending Message"),
                  ));
                },
                child: Text(
                  "Login",
                  style: TextStyle(
                    fontSize: 20.0,
                  ),
                ),
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Text("Don't have account?"),
                  Padding(
                    padding: EdgeInsets.all(4),
                  ),
                  GestureDetector(
                    onTap: () => Navigator.of(context).push(
                        MaterialPageRoute(builder: (context) => Signup())),
                    child: Text(
                      "SignUp",
                      style: TextStyle(
                          color: Colors.red, fontWeight: FontWeight.w600),
                    ),
                  ),
                ],
              )
            ],
          ),
        ),
      ),
    );
  }
}

错误 这是我在 Android Studio 中显示的错误消息。

Handler: "onTap"
Recognizer:
  TapGestureRecognizer#07f5f
════════════════════════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by gesture ═══════════════════════════════════════════════════════════════
The following assertion was thrown while handling a gesture:
Scaffold.of() called with a context that does not contain a Scaffold.

No Scaffold ancestor could be found starting from the context that was passed to Scaffold.of(). This usually happens when the context provided is from the same StatefulWidget as that whose build function actually creates the Scaffold widget being sought.

There are several ways to avoid this problem. The simplest is to use a Builder to get a context that is "under" the Scaffold. For an example of this, please see the documentation for Scaffold.of():
  https://api.flutter.dev/flutter/material/Scaffold/of.html
A more efficient solution is to split your build function into several widgets. This introduces a new context from which you can obtain the Scaffold. In this solution, you would have an outer widget that creates the Scaffold populated by instances of your new inner widgets, and then in these inner widgets you would use Scaffold.of().
A less elegant but more expedient solution is assign a GlobalKey to the Scaffold, then use the key.currentState property to obtain the ScaffoldState rather than using the Scaffold.of() function.

The context used was: Login
  state: _LoginState#f029c
When the exception was thrown, this was the stack: 
#0      Scaffold.of (package:flutter/src/material/scaffold.dart:1451:5)
#1      _LoginState.build.<anonymous closure> (package:flutter_hello/main.dart:57:28)
#2      _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:992:19)
#3      _InkResponseState.build.<anonymous closure> (package:flutter/src/material/ink_well.dart:1098:38)
#4      GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:184:24)
...
Handler: "onTap"
Recognizer: TapGestureRecognizer#07f5f
  debugOwner: GestureDetector
  state: possible
  won arena
  finalPosition: Offset(196.3, 545.3)
  finalLocalPosition: Offset(81.3, 20.2)
  button: 1
  sent tap down

【问题讨论】:

    标签: android android-studio flutter


    【解决方案1】:

    这样做,

    void showInSnackBar(String value) {
        FocusScope.of(context).requestFocus(new FocusNode());
        _scaffoldKey.currentState?.removeCurrentSnackBar();
        _scaffoldKey.currentState.showSnackBar(new SnackBar(
          content: new Text(
            value,
            textAlign: TextAlign.center,
            style: TextStyle(
                color: Colors.white,
                fontSize: 16.0,
               ),
          ),
          backgroundColor: Colors.blue,
          duration: Duration(seconds: 3),
        ));
      }
    

    【讨论】:

      【解决方案2】:

      问题是您使用的上下文不包含 Scaffold,因为 Scaffold 是在上下文之后创建的。您可以通过使用 Builder-Widget 来包装您的内容来解决此问题。

      像这样:

      class _LoginState extends State<Login> {
          @override
          Widget build(BuildContext context) {
              return Scaffold(
                  body: Builder(
                      builder: (context) {
                          // return your body here
                      },
                  ),
              );
         }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-08-19
        • 2021-03-29
        • 2019-05-15
        • 1970-01-01
        • 2023-01-12
        • 1970-01-01
        • 1970-01-01
        • 2016-01-01
        相关资源
        最近更新 更多