Flutter:打开键盘时无法滚动表单 [英] Flutter: Unable to make the Form scroll when the Keyboard is open

查看:81
本文介绍了Flutter:打开键盘时无法滚动表单的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的应用程序中,我正在使用 stack container .在 container 中,我有一个 form 及其字段.下面是我的代码

  import'package:flutter/cupertino.dart';导入'package:flutter/material.dart';导入'package:flutter/widgets.dart';类Login扩展StatelessWidget {@override窗口小部件build(BuildContext context){返回脚手架(backgroundColor:Colors.white,正文:LoginUI(),);}}LoginUI类扩展了StatefulWidget {@override状态< StatefulWidget>createState(){//TODO:实现createState返回LoginState();}}类LoginState扩展State< LoginUI>{final _formKey = GlobalKey< FormState>();@override窗口小部件build(BuildContext context){返回容器(高度:double.infinity,宽度:double.infinity,孩子:堆(适合:StackFit.loose,子代:< Widget> [安全区域(子代:集装箱(边距:EdgeInsets.only(top:25),子级:Image.asset("assets/images/login_image.png"),),),定位(最高:275,子代:集装箱(高度:600,宽度:MediaQuery.of(context).size.width,装饰:新BoxDecoration(颜色:Colors.white,borderRadius:新的BorderRadius.only(topLeft:const Radius.circular(40.0),topRight:const Radius.circular(40.0))),子:列(mainAxisAlignment:MainAxisAlignment.start,子代:< Widget> [排(mainAxisAlignment:MainAxisAlignment.center,子代:< Widget> [灵活的(子代:集装箱(利润:EdgeInsets.only(top:20,left:10,right:10),子:Image.asset("assets/images/logo_2.png"),),)],),形式(子:列(子代:< Widget> [容器(保证金:EdgeInsets.only(最高:40),子代:SizedBox(宽度:MediaQuery.of(context).size.width * .90,高度:36,子级:TextFormField(验证者:(值){如果(value.isEmpty){返回请输入一些文字";}返回null;},装饰:InputDecoration(填满:是的,fillColor:Colors.white,contentPadding:const EdgeInsets.only(顶部:2,底部:2,左侧:8),边框:OutlineInputBorder(borderRadius:BorderRadius.circular(30.0),),hintText:电话",),),)),容器(保证金:EdgeInsets.only(上:15),子代:SizedBox(高度:36,宽度:MediaQuery.of(context).size.width * .90,子级:TextFormField(验证者:(值){如果(value.isEmpty){返回请输入一些文字";}返回null;},装饰:InputDecoration(填满:是的,fillColor:Colors.white,contentPadding:const EdgeInsets.only(顶部:2,底部:2,左侧:8),边框:OutlineInputBorder(borderRadius:BorderRadius.circular(30.0),),hintText:密码",),),),),对齐(对齐方式:Alignment.bottomRight,子代:集装箱(保证金:EdgeInsets.only(上:1,左:10,右:10),子代:FlatButton(onPressed:(){},子代:文字(忘记密码?",样式:TextStyle(fontFamily:"Roboto-Medium",fontSize:14.0,letterSpacing:1.25,颜色:Color.fromRGBO(75,56,137,80))),)),),容器(利润:EdgeInsets.only(top:1,left:10,right:10),子代:SizedBox(宽度:MediaQuery.of(context).size.width * .90,子代:RaisedButton(颜色:Color.fromRGBO(75,56,137,80),textColor:Colors.white,形状:RoundedRectangleBorder(borderRadius:新的BorderRadius.circular(18.0),侧面:BorderSide(颜色:Color.fromRGBO(75,56,137,80))),子代:文字(登录",样式:Theme.of(context).textTheme.button,),onPressed:(){如果(_formKey.currentState.validate()){//如果表单有效,则显示一个Snackbar.Scaffold.of(context).showSnackBar(小吃店(内容:Text('处理数据')));}},),))],),),容器(边距:EdgeInsets.only(顶部:1,左:10,右:10),子代:FlatButton(onPressed:(){},子:RichText(文字:TextSpan(子级:< TextSpan> [TextSpan(文字:还不是会员?",样式:TextStyle(fontFamily:'Roboto-Regular',fontSize:14.0,letterSpacing:0.25,color:Color.fromRGBO(75,56,137,80)),),TextSpan(文字:创建帐户",样式:TextStyle(装饰:TextDecoration.underline,fontFamily:'Roboto-Regular',fontSize:14.0,letterSpacing:0.25,color:Color.fromRGBO(75,56,137,80),),)]),),)),],),),),],)//孩子:Image.asset("assets/images/login_image.png"),);}小部件_buildForm(){退货表格(密钥:_formKey,子:列(子代:< Widget> [排(mainAxisAlignment:MainAxisAlignment.center,子代:< Widget> [灵活的(弹性:1,子代:集装箱(子:ImageIcon(AssetImage("assets/images/email_24px.png"),颜色:Colors.white,),margin:EdgeInsets.only(right:5,bottom:30)),),灵活的(弹性:7子代:SizedBox(高度:80,子级:TextFormField(验证者:(值){如果(value.isEmpty){返回请输入一些文字";}返回null;},装饰:InputDecoration(填满:是的,fillColor:Colors.white,contentPadding:const EdgeInsets.only(top:2,bottom:2,left:8),边框:OutlineInputBorder(borderRadius:BorderRadius.circular(30.0),),hintText:电子邮件",),),))],),容器(边距:EdgeInsets.only(top:20),子级:Row(mainAxisAlignment:MainAxisAlignment.center,子代:< Widget> [灵活的(弹性:1,子代:集装箱(子:ImageIcon(AssetImage("assets/images/lock_24px.png"),颜色:Colors.white,),边距:EdgeInsets.only(右侧:5,底部:30),),),灵活的(弹性:7子代:SizedBox(高度:80,子级:TextFormField(验证者:(值){如果(value.isEmpty){返回请输入一些文字";}返回null;},装饰:InputDecoration(填满:是的,fillColor:Colors.white,contentPadding:const EdgeInsets.only(top:2,bottom:2,left:8),边框:OutlineInputBorder(borderRadius:BorderRadius.circular(30.0),),hintText:密码",),),))],),),容器(子级:Row(mainAxisAlignment:MainAxisAlignment.end,子代:< Widget> [FlatButton(materialTapTargetSize:MaterialTapTargetSize.shrinkWrap,子代:文字(忘记密码?",样式:Theme.of(context).textTheme.body1,),onPressed:(){},),],),),容器(边距:EdgeInsets.only(顶部:40,左侧:25,右侧:10,底部:20),子级:Row(mainAxisAlignment:MainAxisAlignment.center,子代:< Widget> [灵活的(子代:SizedBox(宽度:double.infinity,高度:45,子代:RaisedButton(颜色:Color.fromRGBO(0,72,128,100),textColor:Colors.white,形状:RoundedRectangleBorder(borderRadius:新的BorderRadius.circular(18.0),边:BorderSide(color:Color.fromRGBO(0,72,128,100))),子代:文字(登录",样式:Theme.of(context).textTheme.button,),onPressed:(){如果(_formKey.currentState.validate()){//如果表单有效,则显示一个Snackbar.Scaffold.of(context).showSnackBar(SnackBar(content:Text('Processing Data')));}},),))],),)],),);}@override无效的initState(){//TODO:实现initStatesuper.initState();}} 

我的看法如下

打开键盘时,用户必须将其关闭才能访问 login 按钮.这是因为无法滚动.我尝试在主图像下方添加 SingleScrollView ListView ,然后将其余的内容包装起来,但这没有用.它只会使内容消失.

如何确保 fORM 部分可滚动?

解决方案

您可以使用 SingleChildScrollView ConstrainedBox 包裹整个小部件,如下所示:

  Scaffold(正文:SingleChildScrollView(子代:ConstrainedBox(约束:BoxConstraints(maxHeight:MediaQuery.of(context).size.height),子代:集装箱(子:yourWidget() 

您可以在此处查看相关答案: https://stackoverflow.com/a/59783374/12709039

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?

解决方案

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

这篇关于Flutter:打开键盘时无法滚动表单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆