在颤动中单击 TextFormField 后键盘正在关闭
Posted
技术标签:
【中文标题】在颤动中单击 TextFormField 后键盘正在关闭【英文标题】:Keyboard is closing after clicking on TextFormField in flutter 【发布时间】:2021-06-11 09:46:03 【问题描述】:我在***上尝试了所有可能的答案,仍然无法解决这个问题。 每当我单击任何 TextFormField 时,它都会立即打开和关闭键盘。并且键盘尝试也涵盖了密码字段。
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(),
));
)
],
)
],
),
),
),
)
],
),
),
),
);
我在列上遇到了渲染问题,我也尝试将它放在 SingleChildScrollView 中。
在布局期间抛出了以下断言:A RenderFlex 底部溢出 22 个像素。
相关的导致错误的小部件是:列 file:///D:/android/FlutterApp/metro_prototype/lib/pages/registerPage.dart:29:18 溢出的 RenderFlex 具有 Axis.vertical 的方向。这 溢出的 RenderFlex 边缘已在 用黄色和黑色条纹图案渲染。这通常是 由于内容对于 RenderFlex 来说太大。
考虑应用弹性因子(例如,使用扩展小部件) 强制 RenderFlex 的子级适应可用空间 而不是按照自然大小调整大小。这被认为是 错误条件,因为它表明有内容不能 可见。如果内容合法地大于可用的 空间,请考虑在放置之前使用 ClipRect 小部件对其进行裁剪 在 flex 中,或者使用可滚动容器而不是 Flex,例如 一个列表视图。
具体的 RenderFlex 是:RenderFlex#ee67d relayoutBoundary=up4 OVERFLOWING ... 需要合成 ... parentData:(可以使用大小)...约束: BoxConstraints(0.0
【问题讨论】:
你为什么把FocusScope.of(context).unfocus();
放在构建中,在小部件之前?
@AbdelrahmanSherif 如果我单击屏幕上的任意位置,则从 TextFormFields 中移除焦点。谢谢这有点解决了我的问题。
FocusScope.of(context).unfocus();
的功能是什么?
好吧,试着删除它,看看结果如何。
@basudevnayak 它使键盘失焦,我把它放在了错误的位置。现在键盘问题消失了。即使我专注于任何 TextFormField,我也不知道 build 会被调用
【参考方案1】:
您的代码中有两个问题需要解决。
-
键盘出现后立即消失。
这是因为在你的 Widget 构建函数中你有一个 FocusScope.of(context).unfocus();线。每次键盘出现时,都会重新构建屏幕布局,但在您的情况下,一旦构建完成,您也会移除焦点,因此键盘会返回。我不知道你为什么有那条线,但如果你把它去掉,键盘就会出现并停留。如果出于某种原因必须有该行(即,在第一次构建小部件时,必须移除焦点),则仅将其放在 initState 函数中,而不是在构建函数中。
-
RenderFlex 溢出。
发生这种情况是因为您正在使用一个列,该列通常用于应该完全适合屏幕的布局。在您的情况下,当键盘出现时,屏幕上无法显示所有内容。如果您从顶部删除您的徽标,则有足够的空间,错误就会消失。您有另一个选择(如果您想保留徽标)是用 ListView 替换 Column。
这是对我有用的最终代码:
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(),
));
)
],
)
],
),
),
),
)
],
),
),
),
);
【讨论】:
【参考方案2】:最好的解决方案是将 Column Widget 替换为 ListView Widget。
【讨论】:
以上是关于在颤动中单击 TextFormField 后键盘正在关闭的主要内容,如果未能解决你的问题,请参考以下文章