0

I am new to Flutter, i am creating my login Screen and i want to show a Snackbar in my screen in case of OnPress of Raised Button, But i am unable to show this message to my app. How to resolve this Problem. I also attached the error description in following to understand the main thing, i don't know how to manage it. I used Material Button and Flat Button instead of Raised Button but Problem did not resolved. Image

enter image description here

Code

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

Error Here is my Error Message shown in 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

2 Answers2

2

The Problem is that the context that you are using does not contain a Scaffold, because the Scaffold is created after the context. You can fix this problem by using a Builder-Widget to wrap your content.

Like this:

class _LoginState extends State<Login> {
    @override
    Widget build(BuildContext context) {
        return Scaffold(
            body: Builder(
                builder: (context) {
                    // return your body here
                },
            ),
        );
   }
}
Ruben Röhner
  • 593
  • 4
  • 16
2

Do it like this,

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),
    ));
  }
Madhavam Shahi
  • 1,166
  • 6
  • 17