简体   繁体   中英

SingleChildScrollView is not scrolling with Stack Widget Flutter

Here when I type inside text fields Keyboard covers the Login button. So I need to scroll down to the Login button when typing. I tried wrapping LayoutBuilder with SingleChildScrollView and tried using Positioned widget inside Stack but nothing solved my issue. And I set physics to AlwaysScrollableScrollPhysics() inside SingleChildScrollView but it also didn't solve the problem. I can't figure out what I've done wrong. I would be grateful if anyone can help me with this issue

Here's my code

 Material(
  child: SingleChildScrollView(
    child: Stack(
      overflow: Overflow.clip,
      children: <Widget>[
        Image.asset(
          'assets/login-screen-img.jpg'
        ),
        Padding(
          padding: const EdgeInsets.fromLTRB(16.0, 220.0, 16.0, 0),
          child: Card(
            child: Padding(
              padding: const EdgeInsets.fromLTRB(16.0, 16.0, 16.0, 24.0),
              child: Form(
                //associating global key with the form(It keeps track of the form)
                key: _formKey, 
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  mainAxisSize: MainAxisSize.min,
                  children: <Widget>[
                    Text('Email', style: TextStyle(fontSize: 14.0, color: Colors.grey),),
                    TextFormField(      // email field
                      cursorColor: Colors.brown[500],
                      decoration: InputDecoration(
                        focusedBorder: UnderlineInputBorder(
                          borderSide: BorderSide(color: Colors.brown[500])
                        ),
                        //hintText: 'Enter your Email'
                      ),
                      // validation
                      validator: (email) => email.isEmpty ? 'Enter the email' : null,
                      onChanged: (emailInput) {
                        setState(() {
                          email = emailInput;
                        });
                      },
                    ),
                    SizedBox(height: 16.0),
                    Text('Password', style: TextStyle(fontSize: 14.0, color: Colors.grey),),
                    TextFormField(      // password field
                      cursorColor: Colors.brown[500],
                      decoration: InputDecoration(
                        //hintText: 'Enter your Password'
                        focusedBorder: UnderlineInputBorder(
                          borderSide: BorderSide(color: Colors.brown[500])
                        )
                      ),
                      // validation
                      validator: (password) => password.length < 6 ? 'Password must be more than 6 characters' : null,
                      obscureText: true, // hide when type
                      onChanged: (passwordInput) {
                        setState(() {
                          password = passwordInput;
                        });
                      },
                    ),
                    SizedBox(height: 48.0,),
                    Center(
                      child: RaisedButton(  // login button
                        child: Text('LOG IN', style: TextStyle(fontSize: 16.0, color: Colors.white),),
                        color: Colors.brown[500],
                        shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(25)
                        ),
                        padding: EdgeInsets.fromLTRB(66.0, 16.0, 66.0, 16.0),
                        onPressed: () async {
                          if(_formKey.currentState.validate()) { 
                            // show loading screen
                            setState(() {
                              loading = true;
                            });
    
                            dynamic result = await _auth.signInWithEmailAndPassword(email, password);
    
                            if(result == null) {
                              // stop showing loading screen/widget
                              setState(() {
                                loading = false;
                              });
    
                              // show an error message
                              Fluttertoast.showToast(
                                msg: 'Could not sign in!',
                                toastLength: Toast.LENGTH_SHORT,
                              );
    
                            }
                            
                          }
                        },
                      ),
                    ),
                    SizedBox(height: 24.0),
                    Center(child: Text('Don\'t have and account ?' )),
                    SizedBox(height: 16.0,),
                    Center(
                      child: FlatButton(   // sign up button
                        child: Text('SIGN UP', style: TextStyle(fontSize: 16.0, color: Colors.brown[500] )),
                        onPressed: (){
                          Navigator.push(context, MaterialPageRoute(
                            builder: (context) => SignUp()
                          ));
                        }, 
                      ),
                    )
                  ],
                ),
              ),
            ),
          ),
        )
      ],
    ),
  ),
);

Screenshot of my UI

Here I found that the issue is with the height of the stack. As @sajithlakmal mentioned in the comments, height of the stack is small and there is nothing to scroll. But in my case, I don't want to make an extra height than the screen height because this is just a login screen. I could easily solve the issue by replacing Material widget with Scaffold. inside the body of the Scaffold gives the required height when typing and able to scroll down.

Here's the working code.

Scaffold(
  body: SingleChildScrollView(
      child: Stack(
        overflow: Overflow.visible,
        children: <Widget>[
          Image.asset(
            'assets/login-screen-img.jpg',
             alignment: Alignment.topCenter,
          ),
          Padding(
            padding: const EdgeInsets.fromLTRB(16.0, 220.0, 16.0, 0),
            child: Card(
              child: Padding(
                padding: const EdgeInsets.fromLTRB(16.0, 16.0, 16.0, 24.0),
                child: Form(
                  //associating global key with the form(It keeps track of the form)
                  key: _formKey, 
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    mainAxisSize: MainAxisSize.min,
                    children: <Widget>[
                      Text('Email', style: TextStyle(fontSize: 14.0, color: Colors.grey),),
                      TextFormField(      // email field
                        cursorColor: Colors.brown[500],
                        decoration: InputDecoration(
                          focusedBorder: UnderlineInputBorder(
                            borderSide: BorderSide(color: Colors.brown[500])
                          ),
                          //hintText: 'Enter your Email'
                        ),
                        // validation
                        validator: (email) => email.isEmpty ? 'Enter the email' : null,
                        onChanged: (emailInput) {
                          setState(() {
                            email = emailInput;
                          });
                        },
                      ),
                      SizedBox(height: 16.0),
                      Text('Password', style: TextStyle(fontSize: 14.0, color: Colors.grey),),
                      TextFormField(      // password field
                        cursorColor: Colors.brown[500],
                        decoration: InputDecoration(
                          //hintText: 'Enter your Password'
                          focusedBorder: UnderlineInputBorder(
                            borderSide: BorderSide(color: Colors.brown[500])
                          )
                        ),
                        // validation
                        validator: (password) => password.length < 6 ? 'Password must be more than 6 characters' : null,
                        obscureText: true, // hide when type
                        onChanged: (passwordInput) {
                          setState(() {
                            password = passwordInput;
                          });
                        },
                      ),
                      SizedBox(height: 48.0,),
                      Center(
                        child: RaisedButton(  // login button
                          child: Text('LOG IN', style: TextStyle(fontSize: 16.0, color: Colors.white),),
                          color: Colors.brown[500],
                          shape: RoundedRectangleBorder(
                            borderRadius: BorderRadius.circular(25)
                          ),
                          padding: EdgeInsets.fromLTRB(66.0, 16.0, 66.0, 16.0),
                          onPressed: () async {
                            if(_formKey.currentState.validate()) { // check validation
                              // show loading screen
                              setState(() {
                                loading = true;
                              });
            
                              dynamic result = await _auth.signInWithEmailAndPassword(email, password);
            
                              if(result == null) {
                                // stop showing loading screen/widget
                                setState(() {
                                  loading = false;
                                });
            
                                // show an error message
                                Fluttertoast.showToast(
                                  msg: 'Could not sign in!',
                                  toastLength: Toast.LENGTH_SHORT,
                                );
            
                              }
                              
                            }
                          },
                        ),
                      ),
                      SizedBox(height: 24.0),
                      Center(child: Text('Don\'t have and account ?' )),
                      SizedBox(height: 16.0,),
                      Center(
                        child: FlatButton(   // sign up button
                          child: Text('SIGN UP', style: TextStyle(fontSize: 16.0, color: Colors.brown[500] )),
                          onPressed: (){
                            Navigator.push(context, MaterialPageRoute(
                              builder: (context) => SignUp()
                            ));
                          }, 
                        ),
                      )
                    ],
                  ),
                ),
              ),
            ),
          )
        ],
      ),
    ),
);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM