英文:
Keyboard is hiding textField and screen is not scrolling
问题
你可以尝试在你的代码中包裹整个Column
部分,用SingleChildScrollView
来包装它,这样当键盘弹出时,屏幕可以滚动,让你看到第二个textField
。在你的build
方法中,将Column
替换为以下代码:
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: [
// ...其余的部分...
],
),
),
这应该可以解决在小屏幕设备上键盘遮挡textField
的问题。
英文:
I have the following code for my app:
class LoginPage extends StatefulWidget {
const LoginPage({Key? key}) : super(key: key);
@override
State<LoginPage> createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
String? errorMessage = '';
bool isLogin = true;
final TextEditingController _controllerEmail = TextEditingController();
final TextEditingController _controllerPassword = TextEditingController();
Future<void> signInWithEmailAndPassword() async {
try {
await Auth().signInWithEmailAndPassword(
email: _controllerEmail.text, password: _controllerPassword.text);
} on FirebaseAuthException catch (e) {
setState(() {
errorMessage = e.message;
});
}
}
Future<void> createUserWithEmailAndPassword() async {
try {
await Auth().createUserWithEmailAndPassword(
email: _controllerEmail.text, password: _controllerPassword.text);
} on FirebaseAuthException catch (e) {
setState(() {
errorMessage = e.message;
});
}
}
Widget _title() {
return const Text("MysteryMap");
}
Widget _entryField(String title, TextEditingController controller) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
obscureText: title == 'contraseña' ? true : false,
controller: controller,
decoration: InputDecoration.collapsed(
hintText: title,
),
),
);
}
Widget _errorMessage() {
return Text(
errorMessage! == '' ? '' : '$errorMessage !!!',
style: TextStyle(fontSize: 10, color: Colors.white),
);
}
Widget _submitButton() {
return ElevatedButton(
onPressed: () => isLogin
? signInWithEmailAndPassword()
: createUserWithEmailAndPassword(),
child: Text(
isLogin ? 'Iniciar sesión' : 'Crear cuenta',
style: TextStyle(color: Colors.white),
),
);
}
Widget _loginOrRegisterButton() {
return TextButton(
onPressed: () {
setState(() {
isLogin = !isLogin;
});
},
child: Text(
isLogin ? 'Crear cuenta' : 'Ya tengo cuenta',
style: TextStyle(color: Colors.white),
));
}
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
return SafeArea(
child: Scaffold(
resizeToAvoidBottomInset: false,
body: Container(
width: double.infinity,
height: double.infinity,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/fondo_login.jpeg"),
fit: BoxFit.cover,
),
),
padding: EdgeInsets.all(20),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Row(
children: [
Container(
width: 80,
height: 80,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/app_icon.png"))),
),
Spacer(),
],
),
SizedBox(
height: 100,
),
Align(
alignment: Alignment.topLeft,
child: Text(
"Email",
style: TextStyle(color: Colors.grey, fontSize: 18),
)),
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: const BorderRadius.all(
Radius.circular(100.0),
),
),
child: _entryField('email', _controllerEmail)),
),
SizedBox(
height: 10,
),
Align(
alignment: Alignment.topLeft,
child: Text(
"Contraseña",
style: TextStyle(color: Colors.grey, fontSize: 18),
)),
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: const BorderRadius.all(
Radius.circular(100.0),
),
),
child: _entryField('contraseña', _controllerPassword)),
),
SizedBox(
height: 10,
),
_errorMessage(),
SizedBox(
height: 10,
),
_submitButton(),
SizedBox(
height: 10,
),
_loginOrRegisterButton(),
GestureDetector(
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => Plantilla()));
},
child: Text("fondo"))
],
),
),
),
),
);
}
}
There is no problem on most of device screen sizes.
The problem is on small screen devices, like iPhone 7.
When I want to insert text to the second textField, the keyboard is hiding the textField, and the screen is not scrolling.
What should I change or add into my code to let me see the second textField when writing text using the keyboard?
答案1
得分: 1
以下是翻译好的部分:
"Hey make the SingleChildScrollView
the parent widget everything":
嘿,把 SingleChildScrollView
设为父部件的一切
"return SafeArea(":
返回安全区域(
"child: Scaffold(":
子部件: 脚手架(
"resizeToAvoidBottomInset: false,":
resizeToAvoidBottomInset: false,
"body: SingleChildScrollView(///<===Here":
主体: SingleChildScrollView(///<===这里
"child: Container(":
子部件: 容器(
"width: double.infinity,":
宽度: double.infinity,
"height: double.infinity,":
高度: double.infinity,
"decoration: BoxDecoration(":
装饰: BoxDecoration(
"image: DecorationImage(":
图片: DecorationImage(
"image: AssetImage("assets/fondo_login.jpeg"),":
图片: AssetImage("assets/fondo_login.jpeg"),
"fit: BoxFit.cover,":
适合: BoxFit.cover,
"padding: EdgeInsets.all(20),":
填充: EdgeInsets.all(20),
"child: SingleChildScrollView(///<===You don't need this":
子部件: SingleChildScrollView(///<===这不需要
"child: Column(":
子部件: 列表(
"crossAxisAlignment: CrossAxisAlignment.center,":
横轴对齐: CrossAxisAlignment.center,
"mainAxisAlignment: MainAxisAlignment.start,":
纵轴对齐: MainAxisAlignment.start,
"children: [":
子元素: [
"Container(":
容器(
"width: 80,":
宽度: 80,
"height: 80,":
高度: 80,
"decoration: BoxDecoration(":
装饰: BoxDecoration(
"image: DecorationImage(":
图片: DecorationImage(
"image: AssetImage("assets/app_icon.png"))),":
图片: AssetImage("assets/app_icon.png"))),
"Spacer(),":
Spacer(),
"SizedBox(":
SizedBox(
"height: 100,":
高度: 100,
"Align(":
对齐(
"alignment: Alignment.topLeft,":
对齐方式: Alignment.topLeft,
"child: Text(":
子部件: 文本(
""Email",":
"Email",
"style: TextStyle(color: Colors.grey, fontSize: 18),":
样式: TextStyle(color: Colors.grey, fontSize: 18),
"Padding(":
填充(
"padding: const EdgeInsets.all(8.0),":
填充: const EdgeInsets.all(8.0),
"child: Container(":
子部件: 容器(
"decoration: BoxDecoration(":
装饰: BoxDecoration(
"color: Colors.white,":
颜色: Colors.white,
"borderRadius: const BorderRadius.all(Radius.circular(100.0)),":
边框半径: const BorderRadius.all(Radius.circular(100.0)),
"child: _entryField('email', _controllerEmail)),":
子部件: _entryField('email', _controllerEmail)),
"SizedBox(":
SizedBox(
"height: 10,":
高度: 10,
"Align(":
对齐(
"alignment: Alignment.topLeft,":
对齐方式: Alignment.topLeft,
"child: Text(":
子部件: 文本(
""Contraseña",":
"Contraseña",
"style: TextStyle(color: Colors.grey, fontSize: 18),":
样式: TextStyle(color: Colors.grey, fontSize: 18),
"Padding(":
填充(
"padding: const EdgeInsets.all(8.0),":
填充: const EdgeInsets.all(8.0),
"child: Container(":
子部件: 容器(
"decoration: BoxDecoration(":
装饰: BoxDecoration(
"color: Colors.white,":
颜色: Colors.white,
"borderRadius: const BorderRadius.all(Radius.circular(100.0)),":
边框半径: const BorderRadius.all(Radius.circular(100.0)),
"child: _entryField('contraseña', _controllerPassword)),":
子部件: _entryField('contraseña', _controllerPassword)),
"SizedBox(":
SizedBox(
"height: 10,":
高度: 10,
"_errorMessage(),":
_errorMessage(),
"SizedBox(":
SizedBox(
"height: 10,":
高度: 10,
"_submitButton(),":
_submitButton(),
"SizedBox(":
SizedBox(
"height: 10,":
高度: 10,
"_loginOrRegisterButton(),":
_loginOrRegisterButton(),
"GestureDetector(":
GestureDetector(
"onTap: () {":
onTap: () {
"Navigator.of(context).push(MaterialPageRoute(builder: (context) => Plantilla()));":
Navigator.of(context).push(MaterialPageRoute(builder: (context) => Plantilla()));
"child: Text("fondo"))":
子部件: Text("fondo"))
英文:
Hey make the SingleChildScrollview
the parent widget everything
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
return SafeArea(
child: Scaffold(
resizeToAvoidBottomInset: false,
body: SingleChildScrollView(///<===Here
child: Container(
width: double.infinity,//I'd advice you to use MediaQuery width of the device
height: double.infinity,//I'd advice you to use MediaQuery height of the device
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/fondo_login.jpeg"),
fit: BoxFit.cover,
),
),
padding: EdgeInsets.all(20),
child: SingleChildScrollView(///<===You don't need this
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Row(
children: [
Container(
width: 80,
height: 80,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/app_icon.png"))),
),
Spacer(),
],
),
SizedBox(
height: 100,
),
Align(
alignment: Alignment.topLeft,
child: Text(
"Email",
style: TextStyle(color: Colors.grey, fontSize: 18),
)),
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: const BorderRadius.all(
Radius.circular(100.0),
),
),
child: _entryField('email', _controllerEmail)),
),
SizedBox(
height: 10,
),
Align(
alignment: Alignment.topLeft,
child: Text(
"Contraseña",
style: TextStyle(color: Colors.grey, fontSize: 18),
)),
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: const BorderRadius.all(
Radius.circular(100.0),
),
),
child: _entryField('contraseña', _controllerPassword)),
),
SizedBox(
height: 10,
),
_errorMessage(),
SizedBox(
height: 10,
),
_submitButton(),
SizedBox(
height: 10,
),
_loginOrRegisterButton(),
GestureDetector(
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => Plantilla()));
},
child: Text("fondo"))
],
),
),
),
),
);
}
}
</details>
# 答案2
**得分**: 1
resizeToAvoidBottomInset: true,
<details>
<summary>英文:</summary>
Try with these changes
resizeToAvoidBottomInset: true,
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论