【发布时间】:2021-10-11 04:52:46
【问题描述】:
我在打开键盘时遇到 Flutter 报告溢出问题。这是打开键盘或验证表单或字段时我的视图的外观和行为:
有没有办法让顶部(“大标题”和“lorem ipsum”)小部件在发生这种情况时自动调整大小,以便表单字段和提交按钮可见?
这发生在元素位于Column 小部件中的位置。
我已经知道resizeToAvoidBottomInset ,但我不想使用它,因为我不想挡住键盘下方的任何小部件。
我也知道我可以使用SingleChildScrollView,但我也不想使用它,因为我希望“提交”按钮在键盘启动时可见。
您可以查看gist 以查看此确切代码:
import 'package:flutter/material.dart';
import 'dart:math';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key}) : super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
bool _hasError = false;
bool _usernameHasError = false;
bool _passwordHasError = false;
_handleFormSubmission() {
final rand = Random();
setState(() {
_hasError = rand.nextBool();
});
print('Sumbmitted');
}
_handleUsernameChange(String value) {
setState(() {
_usernameHasError = value.isEmpty;
});
}
_handlePasswordChange(String value) {
setState(() {
_passwordHasError = value.isEmpty;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
padding: const EdgeInsets.all(10.0).add(const EdgeInsets.only(top: 30.0)),
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
child: Column(children: [
Text('Large title',
style: Theme.of(context).textTheme.headline2),
Text(
'Lorem ipsum dolor sit amet, consectetur adipiscing elit, '
'sed do eiusmod tempor incididunt ut labore et dolore magna'
' aliqua. Ut enim ad minim veniam, quis nostrud exercitation '
'ullamco laboris nisi ut aliquip ex ea commodo consequat.',
style: Theme.of(context).textTheme.headline5),
]),
),
Container(
padding: const EdgeInsets.only(top: 10.0),
child: Column(children: [
Container(
alignment: Alignment.centerLeft,
padding: const EdgeInsets.only(bottom: 20.0),
child: Text('Additional information is placed here')),
TextFormField(
decoration: InputDecoration(
labelText: 'Username',
errorText: _usernameHasError ? 'Invalid username' : null),
onChanged: _handleUsernameChange,
),
TextFormField(
obscureText: true,
decoration: InputDecoration(
labelText: 'Password',
errorText: _passwordHasError ? 'Invalid password' : null),
onChanged: _handlePasswordChange,
),
_hasError
? Container(
padding: const EdgeInsets.symmetric(vertical: 20.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.error,
color: Theme.of(context).errorColor),
Text('An error occurred!',
style: TextStyle(
color: Theme.of(context).errorColor))
]))
: Container()
]),
),
Container(
padding: const EdgeInsets.only(top: 10.0),
child: Column(children: [
Container(
width: double.infinity,
child: ElevatedButton(
child: Text('Submit'),
onPressed: _handleFormSubmission,
)),
])),
]),
));
}
}
当您查看我的 GIF 时,您还可以看到键盘向上并不是唯一可以调整视图大小的东西,还会弹出错误消息。
我认为一个好的解决方案是动态调整顶部的文本“Large title”和“Lorem ipsum”文本的大小,以便为表单和按钮腾出空间。
我不确定是否有可靠的方法来检测键盘何时启动,但我已经阅读了有关在 this question 中检查 MediaQuery.of(context).viewInsets.bottom 的信息。当键盘打开时,我可以调整文本大小(或隐藏它)。这是可行的解决方案吗?
或者也许有一些我不知道的布局?最好在顶部为两个小部件设置动画,这样它们会逐渐消失和/或减小尺寸(可能是AnimatedContainer)?这仍然需要以编程方式检查打开的键盘。
感谢任何建议!
【问题讨论】:
标签: flutter dart user-interface mobile