Flutter: Unable to make the Form scroll when the Keyboard is open

自闭症网瘾萝莉.ら 提交于 2021-02-11 16:57:42

问题


In my application, I am using a stack and a container. Within the container i have a form and its fields. Below is my code

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

import 'package:flutter/widgets.dart';

class Login extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: LoginUI(),
    );
  }
}

class LoginUI extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return LoginState();
  }
}

class LoginState extends State<LoginUI> {
  final _formKey = GlobalKey<FormState>();

  @override
  Widget build(BuildContext context) {
    return Container(
        height: double.infinity,
        width: double.infinity,
        child:
         Stack(
          fit: StackFit.loose,
          children: <Widget>[
            SafeArea(
              child: Container(
                margin: EdgeInsets.only(top: 25),
                child: Image.asset("assets/images/login_image.png"),
              ),
            ),

            Positioned(
              top: 275,
              child: Container(
                height: 600,
                width: MediaQuery.of(context).size.width,
                decoration: new BoxDecoration(
                    color: Colors.white,
                    borderRadius: new BorderRadius.only(
                        topLeft: const Radius.circular(40.0),
                        topRight: const Radius.circular(40.0))),
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.start,
                  children: <Widget>[
                    Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: <Widget>[
                        Flexible(
                          child: Container(
                            margin:
                                EdgeInsets.only(top: 20, left: 10, right: 10),
                            child: Image.asset(
                                "assets/images/logo_2.png"),
                          ),
                        )
                      ],
                    ),
                    Form(
                      child: Column(
                        children: <Widget>[
                          Container(
                              margin: EdgeInsets.only(
                                top: 40,
                              ),
                              child: SizedBox(
                                width: MediaQuery.of(context).size.width * .90,
                                height: 36,
                                child: TextFormField(
                                  validator: (value) {
                                    if (value.isEmpty) {
                                      return 'Please enter some text';
                                    }
                                    return null;
                                  },
                                  decoration: InputDecoration(
                                    filled: true,
                                    fillColor: Colors.white,
                                    contentPadding: const EdgeInsets.only(
                                        top: 2, bottom: 2, left: 8),
                                    border: OutlineInputBorder(
                                      borderRadius: BorderRadius.circular(30.0),
                                    ),
                                    hintText: "Phone",
                                  ),
                                ),
                              )),
                          Container(
                            margin: EdgeInsets.only(
                              top: 15,
                            ),
                            child: SizedBox(
                              height: 36,
                              width: MediaQuery.of(context).size.width * .90,
                              child: TextFormField(
                                validator: (value) {
                                  if (value.isEmpty) {
                                    return 'Please enter some text';
                                  }
                                  return null;
                                },
                                decoration: InputDecoration(
                                  filled: true,
                                  fillColor: Colors.white,
                                  contentPadding: const EdgeInsets.only(
                                      top: 2, bottom: 2, left: 8),
                                  border: OutlineInputBorder(
                                    borderRadius: BorderRadius.circular(30.0),
                                  ),
                                  hintText: "Password",
                                ),
                              ),
                            ),
                          ),
                          Align(
                            alignment: Alignment.bottomRight,
                            child: Container(
                                margin: EdgeInsets.only(
                                    top: 1, left: 10, right: 10),
                                child: FlatButton(
                                  onPressed: () {},
                                  child: Text("Forgot Password?",
                                      style: TextStyle(
                                          fontFamily: 'Roboto-Medium',
                                          fontSize: 14.0,
                                          letterSpacing: 1.25,
                                          color:
                                              Color.fromRGBO(75, 56, 137, 80))),
                                )),
                          ),
                          Container(
                              margin:
                                  EdgeInsets.only(top: 1, left: 10, right: 10),
                              child: SizedBox(
                                width: MediaQuery.of(context).size.width * .90,
                                child: RaisedButton(
                                  color: Color.fromRGBO(75, 56, 137, 80),
                                  textColor: Colors.white,
                                  shape: RoundedRectangleBorder(
                                      borderRadius:
                                          new BorderRadius.circular(18.0),
                                      side: BorderSide(
                                          color:
                                              Color.fromRGBO(75, 56, 137, 80))),
                                  child: Text(
                                    "LOGIN",
                                    style: Theme.of(context).textTheme.button,
                                  ),
                                  onPressed: () {
                                    if (_formKey.currentState.validate()) {
                                      // If the form is valid, display a Snackbar.
                                      Scaffold.of(context).showSnackBar(
                                          SnackBar(
                                              content:
                                                  Text('Processing Data')));
                                    }
                                  },
                                ),
                              ))
                        ],
                      ),
                    ),
                    Container(
                        margin: EdgeInsets.only(top: 1, left: 10, right: 10),
                        child: FlatButton(
                          onPressed: () {},
                          child: RichText(
                            text: TextSpan(children: <TextSpan>[
                              TextSpan(
                                text: "Not a member yet? ",
                                style: TextStyle(fontFamily: 'Roboto-Regular',  fontSize: 14.0, letterSpacing: 0.25, color:Color.fromRGBO(75, 56, 137, 80 )),
                              ),
                              TextSpan(
                                text: "Create an Account",
                                style: TextStyle(decoration: TextDecoration.underline,  fontFamily: 'Roboto-Regular',  fontSize: 14.0, letterSpacing: 0.25, color:Color.fromRGBO(75, 56, 137, 80 ),
                              ),)
                            ]),
                          ),
                        )),
                  ],
                ),
              ),
            ),
          ],
        )
        //child: Image.asset("assets/images/login_image.png"),
        );
  }

  Widget _buildForm() {
    return Form(
      key: _formKey,
      child: Column(
        children: <Widget>[
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Flexible(
                flex: 1,
                child: Container(
                    child: ImageIcon(
                      AssetImage("assets/images/email_24px.png"),
                      color: Colors.white,
                    ),
                    margin: EdgeInsets.only(right: 5, bottom: 30)),
              ),
              Flexible(
                  flex: 7,
                  child: SizedBox(
                    height: 80,
                    child: TextFormField(
                      validator: (value) {
                        if (value.isEmpty) {
                          return 'Please enter some text';
                        }
                        return null;
                      },
                      decoration: InputDecoration(
                        filled: true,
                        fillColor: Colors.white,
                        contentPadding:
                            const EdgeInsets.only(top: 2, bottom: 2, left: 8),
                        border: OutlineInputBorder(
                          borderRadius: BorderRadius.circular(30.0),
                        ),
                        hintText: "Email",
                      ),
                    ),
                  ))
            ],
          ),
          Container(
            margin: EdgeInsets.only(top: 20),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Flexible(
                  flex: 1,
                  child: Container(
                    child: ImageIcon(
                      AssetImage("assets/images/lock_24px.png"),
                      color: Colors.white,
                    ),
                    margin: EdgeInsets.only(right: 5, bottom: 30),
                  ),
                ),
                Flexible(
                    flex: 7,
                    child: SizedBox(
                      height: 80,
                      child: TextFormField(
                        validator: (value) {
                          if (value.isEmpty) {
                            return 'Please enter some text';
                          }
                          return null;
                        },
                        decoration: InputDecoration(
                          filled: true,
                          fillColor: Colors.white,
                          contentPadding:
                              const EdgeInsets.only(top: 2, bottom: 2, left: 8),
                          border: OutlineInputBorder(
                            borderRadius: BorderRadius.circular(30.0),
                          ),
                          hintText: "Password",
                        ),
                      ),
                    ))
              ],
            ),
          ),
          Container(
            child: Row(
              mainAxisAlignment: MainAxisAlignment.end,
              children: <Widget>[
                FlatButton(
                  materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
                  child: Text(
                    "Forgot Password?",
                    style: Theme.of(context).textTheme.body1,
                  ),
                  onPressed: () {},
                ),
              ],
            ),
          ),
          Container(
            margin: EdgeInsets.only(top: 40, left: 25, right: 10, bottom: 20),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Flexible(
                    child: SizedBox(
                  width: double.infinity,
                  height: 45,
                  child: RaisedButton(
                    color: Color.fromRGBO(0, 72, 128, 100),
                    textColor: Colors.white,
                    shape: RoundedRectangleBorder(
                        borderRadius: new BorderRadius.circular(18.0),
                        side:
                            BorderSide(color: Color.fromRGBO(0, 72, 128, 100))),
                    child: Text(
                      "LOGIN",
                      style: Theme.of(context).textTheme.button,
                    ),
                    onPressed: () {
                      if (_formKey.currentState.validate()) {
                        // If the form is valid, display a Snackbar.
                        Scaffold.of(context).showSnackBar(
                            SnackBar(content: Text('Processing Data')));
                      }
                    },
                  ),
                ))
              ],
            ),
          )
        ],
      ),
    );
  }

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
  }
}

My view is as follows

when the keyboard is open, the user must close it to access the login button. This is because this cannot be scrolled. I tried adding SingleScrollView and ListView below the main image and wrap the rest with it, but that didnt work. It only made the content disappear.

How can i make sure the fORM section is scrollable?


回答1:


You can wrap your whole widget with SingleChildScrollView and then ConstrainedBox as follows:

Scaffold(
  body: SingleChildScrollView(
    child: ConstrainedBox(
      constraints: BoxConstraints(maxHeight: MediaQuery.of(context).size.height),
      child: Container(
        child: yourWidget()

You can see the related answer here: https://stackoverflow.com/a/59783374/12709039



来源:https://stackoverflow.com/questions/60072434/flutter-unable-to-make-the-form-scroll-when-the-keyboard-is-open

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!