简体   繁体   English

单击 flutter 中的 TextFormField 后键盘正在关闭

[英]Keyboard is closing after clicking on TextFormField in flutter

I tried every possible answer on stackoverflow, still not able to solve this problem.我在stackoverflow上尝试了所有可能的答案,仍然无法解决这个问题。 Whenever I click on any TextFormField, it opens and closes keyboard immediately.每当我单击任何 TextFormField 时,它都会立即打开和关闭键盘。 And also keyboard tries covers password fields.并且键盘尝试也涵盖了密码字段。

import 'package:flutter/material.dart';
import 'package:metro_prototype/pages/loginPage.dart';

import '../uiConstsants.dart';

class RegisterPage extends StatefulWidget {
  static final String routeName = "/registerPage";

  @override
  _RegisterPageState createState() => _RegisterPageState();
}

class _RegisterPageState extends State<RegisterPage> {
  @override
  Widget build(BuildContext context) {
    var width = MediaQuery.of(context).size.width;

    FocusScope.of(context).unfocus();
    return Scaffold(
      body: GestureDetector(
        onTap: () => FocusScope.of(context).unfocus(),
        child: Container(
          decoration: BoxDecoration(
              gradient: LinearGradient(
                  begin: Alignment.topCenter,
                  end: Alignment.bottomCenter,
                  colors: [Colors.white, color1])),
          //#002D72
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              Hero(
                tag: 'logo',
                child: Padding(
                  padding:
                      const EdgeInsets.only(left: 100, right: 100, bottom: 30),
                  child: ClipOval(
                    child: Image.asset(
                      'images/haiko1.jpg',
                      height: width / 4,
                      width: width / 4,
                    ),
                  ),
                ),
              ),
              Padding(
                padding: const EdgeInsets.all(20.0),
                child: Container(
                  decoration: BoxDecoration(
                      color: Colors.white,
                      borderRadius: BorderRadius.circular(15)),
                  child: Padding(
                    padding: const EdgeInsets.all(25.0),
                    child: Column(
                      children: [
                        TextFormField(
                          decoration: textfield1Deco.copyWith(
                            prefixIcon: Icon(Icons.account_circle),
                            hintText: "Enter your name",
                            labelText: "Name",
                          ),
                        ),
                        SizedBox(height: 30),
                        TextFormField(
                          decoration: textfield1Deco.copyWith(
                              prefixIcon: Icon(Icons.phone),
                              hintText: "Enter your mobile number",
                              labelText: "Mobile Number"),
                        ),
                        SizedBox(height: 30),
                        TextFormField(
                          decoration: textfield1Deco.copyWith(
                            prefixIcon: Icon(Icons.lock),
                            hintText: "Enter your password",
                            labelText: "Password",
                          ),
                        ),
                        SizedBox(height: 30),
                        TextFormField(
                          decoration: textfield1Deco.copyWith(
                            prefixIcon: Icon(Icons.lock),
                            hintText: "Enter your password",
                            labelText: "Password",
                          ),
                        ),
                        SizedBox(height: 30),
                        Row(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: [
                            getButton("Register", Icons.person_add, () {
                              Navigator.pop(
                                  context,
                                  PageRouteBuilder(
                                    transitionDuration:
                                        Duration(milliseconds: 2000),
                                    pageBuilder: (_, __, ___) => LoginPage(),
                                  ));
                            })
                          ],
                        )
                      ],
                    ),
                  ),
                ),
              )
            ],
          ),
        ),
      ),
    );
  }
}

I am getting render problem on column, I also tried putting it in SingleChildScrolView.我在列上遇到渲染问题,我也尝试将它放在 SingleChildScrollView 中。

The following assertion was thrown during layout: A RenderFlex overflowed by 22 pixels on the bottom.布局期间引发了以下断言: A RenderFlex 在底部溢出了 22 个像素。

The relevant error-causing widget was: Column file:///D:/Android/FlutterApp/metro_prototype/lib/pages/registerPage.dart:29:18 The overflowing RenderFlex has an orientation of Axis.vertical.相关的导致错误的小部件是:Column file:///D:/Android/FlutterApp/metro_prototype/lib/pages/registerPage.dart:29:18 溢出的 RenderFlex 的方向为 Axis.vertical。 The edge of the RenderFlex that is overflowing has been marked in the rendering with a yellow and black striped pattern.溢出的 RenderFlex 边缘已在渲染中用黄色和黑色条纹图案标记。 This is usually caused by the contents being too big for the RenderFlex.这通常是由于内容对于 RenderFlex 来说太大了。

Consider applying a flex factor (eg using an Expanded widget) to force the children of the RenderFlex to fit within the available space instead of being sized to their natural size.考虑应用弹性因子(例如,使用 Expanded 小部件)来强制 RenderFlex 的子级适应可用空间,而不是调整到它们的自然大小。 This is considered an error condition because it indicates that there is content that cannot be seen.这被认为是一种错误情况,因为它表明存在看不到的内容。 If the content is legitimately bigger than the available space, consider clipping it with a ClipRect widget before putting it in the flex, or using a scrollable container rather than a Flex, like a ListView.如果内容合法地大于可用空间,请考虑在将其放入 flex 之前使用 ClipRect 小部件对其进行剪辑,或者使用可滚动容器而不是 Flex,例如 ListView。

The specific RenderFlex in question is: RenderFlex#ee67d relayoutBoundary=up4 OVERFLOWING... needs compositing... parentData: (can use size)... constraints: BoxConstraints(0.0<=w<=411.4, 0.0<=h<=561.1)... size: Size(411.4, 561.1)... direction: vertical... mainAxisAlignment: center... mainAxisSize: max... crossAxisAlignment: center... verticalDirection: down有问题的具体 RenderFlex 是:RenderFlex#ee67d relayoutBoundary=up4 OVERFLOWING...需要合成... parentData:(可以使用大小)...约束:BoxConstraints(0.0<=w<=411.4, 0.0<=h<= 561.1)...尺寸:尺寸(411.4,561.1)...方向:垂直... mainAxisAlignment:中心... mainAxisSize:最大... crossAxisAlignment:中心...垂直方向:向下

There are two problems to tackle in your code.您的代码中有两个问题需要解决。

  1. Keyboard disappearing right after appearing.键盘出现后立即消失。

This is being caused because in your Widget build function you have a FocusScope.of(context).unfocus();这是因为在您的 Widget 构建中 function 您有一个 FocusScope.of(context).unfocus(); line.线。 Every time the keyboard comes up, a screen layout is rebuilt, but in your case, as soon as it's built, you're also removing focus, so the keyboard goes back down.每次键盘出现时,都会重新构建屏幕布局,但在您的情况下,一旦构建完成,您也会移除焦点,因此键盘会返回。 I'm not sure why you have that line, but if you remove it, the keyboard comes up and stays.我不知道你为什么有那条线,但如果你把它去掉,键盘就会出现并停留。 If you must have the line for some reason (ie, when the widget is first built, the focus must be removed), then put it only in the initState function, not the build function.如果由于某种原因必须有该行(即,在第一次构建小部件时,必须移除焦点),则仅将其放入 initState function,而不是构建 function。

  1. RenderFlex overflow. RenderFlex 溢出。

This is happening because you are using a column, which is generally used for a layout that's supposed to entirely fit in the screen.发生这种情况是因为您正在使用一个列,该列通常用于应该完全适合屏幕的布局。 In your case, when the keyboard comes up, everything can't be fit on the screen.在您的情况下,当键盘出现时,屏幕上无法显示所有内容。 If you remove your logo from the top, there's enough space and the error goes away.如果您从顶部删除您的徽标,则有足够的空间,错误就会消失。 Another option you have (if you want to keep the logo) is to replace the Column with a ListView.您拥有的另一个选择(如果您想保留徽标)是用 ListView 替换 Column。

This is the final code that's working for me:这是为我工作的最终代码:

import 'package:flutter/material.dart';
import 'package:metro_prototype/pages/loginPage.dart';
import '../uiConstsants.dart';

class RegisterPage extends StatefulWidget {
  static final String routeName = "/registerPage";

  @override
  _RegisterPageState createState() => _RegisterPageState();
}

class _RegisterPageState extends State<RegisterPage> {

  @override
  void initState() {
    super.initState();
    FocusScope.of(context).unfocus();
  }

  @override
  Widget build(BuildContext context) {
    var width = MediaQuery.of(context).size.width;

    // FocusScope.of(context).unfocus();
    return Scaffold(
      resizeToAvoidBottomInset: true,
      body: GestureDetector(
        onTap: () => FocusScope.of(context).unfocus(),
        child: Container(
          decoration: BoxDecoration(
              gradient: LinearGradient(
                  begin: Alignment.topCenter,
                  end: Alignment.bottomCenter,
                  colors: [Colors.white, color1])),
          //#002D72
          child: ListView(
            // mainAxisAlignment: MainAxisAlignment.center,
            // crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              Hero(
                tag: 'logo',
                child: Padding(
                  padding:
                      const EdgeInsets.only(left: 100, right: 100, bottom: 30),
                  child: ClipOval(
                    child: Image.asset(
                      'images/haiko1.jpg',
                      height: width / 4,
                      width: width / 4,
                    ),
                  ),
                ),
              ),
              Padding(
                padding: const EdgeInsets.all(20.0),
                child: Container(
                  decoration: BoxDecoration(
                      color: Colors.white,
                      borderRadius: BorderRadius.circular(15)),
                  child: Padding(
                    padding: const EdgeInsets.all(25.0),
                    child: Column(
                      children: [
                        TextFormField(
                          decoration: InputDecoration(
                            prefixIcon: Icon(Icons.account_circle),
                            hintText: "Enter your name",
                            labelText: "Name",
                          ),
                        ),
                        SizedBox(height: 30),
                        TextFormField(
                          decoration: InputDecoration(
                              prefixIcon: Icon(Icons.phone),
                              hintText: "Enter your mobile number",
                              labelText: "Mobile Number"),
                        ),
                        SizedBox(height: 30),
                        TextFormField(
                          decoration: InputDecoration(
                            prefixIcon: Icon(Icons.lock),
                            hintText: "Enter your password",
                            labelText: "Password",
                          ),
                        ),
                        SizedBox(height: 30),
                        TextFormField(
                          decoration: InputDecoration(
                            prefixIcon: Icon(Icons.lock),
                            hintText: "Enter your password",
                            labelText: "Password",
                          ),
                        ),
                        SizedBox(height: 30),
                        Row(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: [
                            getButton("Register", Icons.person_add, () {
                              Navigator.pop(
                                  context,
                                  PageRouteBuilder(
                                    transitionDuration:
                                        Duration(milliseconds: 2000),
                                    pageBuilder: (_, __, ___) => LoginPage(),
                                  ));
                            })
                          ],
                        )
                      ],
                    ),
                  ),
                ),
              )
            ],
          ),
        ),
      ),
    );
  }
}

The best possible solution would be to replace the Column Widget with a ListView Widget .最好的解决方案是用 ListView Widget 替换 Column Widget

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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