Flutter:如何制作超过一屏的Form
Posted
技术标签:
【中文标题】Flutter:如何制作超过一屏的Form【英文标题】:Flutter: How to make a Form that is longer than one screen 【发布时间】:2021-06-02 18:47:51 【问题描述】:我想通过验证制作一个非常基本的颤振form。但是,我的问题会比一个屏幕上显示的要多,所以我将表单字段放在ListView 中,如下所示:
class SurveyView extends StatefulWidget
final Iterable<String> questions;
const SurveyView(this.questions, Key? key) : super(key: key);
@override
_SurveyViewState createState() => _SurveyViewState();
class _SurveyViewState extends State<SurveyView>
final _formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context)
return Column(
children: [
Expanded(
child: Form(
key: _formKey,
child: ListView(
padding: const EdgeInsets.fromLTRB(0, 0, 0, 10),
children: widget.questions
.map((q) => SurveyQuestionView(q))
.toList()
.cast<Widget>() +
[
ElevatedButton(
onPressed: ()
if (_formKey.currentState!.validate())
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text('Ok!')));
else
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text('Some form fields missing')));
,
child: Text("Submit")),
],
),
),
),
],
);
class SurveyQuestionView extends StatelessWidget
final String question;
const SurveyQuestionView(this.question, Key? key) : super(key: key);
@override
Widget build(BuildContext context)
return Container(
padding: EdgeInsets.fromLTRB(10, 10, 10, 0),
width: double.maxFinite,
child: Card(
elevation: 5,
child: Container(
padding: EdgeInsets.all(10),
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Text(question),
TextFormField(
validator: (value)
if (value == null value.isEmpty)
return 'Please enter a value';
,
),
]),
),
),
);
这对一些字段很有效,但是当列表变得太长时,离屏幕太远的值似乎会丢失。当我单击“提交”时,验证仅在当前屏幕开始之后一点点上升。我假设这是对长列表的优化,但是如何保存我的状态并使表单验证检查整个列表。我尝试将SurveyQuestionView
转换为有状态并在文本字段中使用controllers,但这没有帮助。
我是否只需要手动完成所有表单验证?或者有什么方法可以让内置的表单来处理这个问题?
或者,列表永远不会那么长。是否可以关闭此优化或使用其他类型的滚动视图?
【问题讨论】:
将表单字段放在单个滚动视图内的列中 【参考方案1】:如果您将小部件放入列中,则应关闭优化。但是你不能直接滚动一列。输入 SingleChildScrollView。它是一个小部件,可让您滚动将成为其子级的单个小部件。
所以更改此代码:
Form(
key: _formKey,
child: ListView(
etc.
到
Form(
key: _formKey,
child: SingleChildScrollView(
child: Column(
etc.
【讨论】:
这确实有效,尽管它仍然不会自动滚动到第一个错误。在使用 Form 时能够保持实际 ListView 的性能优势会很好,但我想这是不可能的 我明白了。我相信我误解了你的问题。当您说“验证只增加一点”时,我假设您的意思是屏幕外项目的实际验证功能不起作用。但是,如果我理解正确,验证是有效的,但是如果屏幕外的某些内容在验证期间出现错误,它不会自动滚动到视图中,对吗?我看看能不能找到解决办法。 不,你是对的。以前,验证对屏幕外的项目根本不起作用,但它会自动滚动到它验证的第一个项目。使用此解决方案,实际验证工作正常,但似乎根本不会自动滚动,这是可以容忍的。以上是关于Flutter:如何制作超过一屏的Form的主要内容,如果未能解决你的问题,请参考以下文章
XCUI 测试:app.debugDescription 显示最后一屏的信息
swiper在vue中使用,纵向滚动翻页,超出一屏的解决方案