gpt4 book ai didi

android - Flutter - 如何使用包含表单的可扩展面板构建 ListView ?

转载 作者:IT王子 更新时间:2023-10-29 07:00:29 28 4
gpt4 key购买 nike

我正在尝试在 ListView 中的可扩展面板内构建表单。

我想我快要搞定了,但我一直遇到视口(viewport)高度错误的问题。错误是这样说的:

══╡渲染库捕获异常╞══════════════════════════════════════════════ ══════════════════════
在 performResize() 期间抛出了以下断言:
垂直视口(viewport)被赋予无限高度。
视口(viewport)在滚动方向扩展以填充它们的容器。在这种情况下,垂直
viewport 被赋予了无限量的垂直空间来扩展。这个情况
当一个可滚动小部件嵌套在另一个可滚动小部件中时,通常会发生这种情况。
如果此小部件始终嵌套在可滚动小部件中,则无需使用视口(viewport),因为
总会有足够的垂直空间供 children 使用。在这种情况下,请考虑使用 Column
反而。否则,请考虑使用“shrinkWrap”属性(或 ShrinkWrappingViewport)调整大小
视口(viewport)的高度与其子级的高度之和。

从几个在线资源中,我想到了将每个表单创建为小部件并创建要包含在 ListView 中的可扩展面板列表的想法。 ListView 是应用程序的主体。

到目前为止,我的代码如下所示:

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'App',
home: Interview(),
);
}
}

class Interview extends StatefulWidget {
@override
InterviewState createState() => new InterviewState();
}

class ExpansionPanelRow {
bool isExpanded;
final String header;
final Widget body;
final Icon icon;
ExpansionPanelRow(this.isExpanded, this.header, this.body, this.icon);
}

class InterviewState extends State<Interview> {
final GlobalKey<FormState> _formKey = new GlobalKey<FormState>();
List<String> _colors = <String>['', 'red', 'green', 'blue', 'orange'];
String _color = '';

Widget interviewDataForm() {
return new SafeArea(
top: false,
bottom: false,
child: Form(
key: _formKey,
autovalidate: true,
child: new ListView(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
children: <Widget>[
new TextFormField(
decoration: const InputDecoration(
icon: const Icon(Icons.person),
hintText: 'Enter your first and last name',
labelText: 'Name',
),
),
new TextFormField(
decoration: const InputDecoration(
icon: const Icon(Icons.calendar_today),
hintText: 'Enter your date of birth',
labelText: 'Dob',
),
keyboardType: TextInputType.datetime,
),
new TextFormField(
decoration: const InputDecoration(
icon: const Icon(Icons.phone),
hintText: 'Enter a phone number',
labelText: 'Phone',
),
keyboardType: TextInputType.phone,
inputFormatters: [
WhitelistingTextInputFormatter.digitsOnly,
],
),
new TextFormField(
decoration: const InputDecoration(
icon: const Icon(Icons.email),
hintText: 'Enter a email address',
labelText: 'Email',
),
keyboardType: TextInputType.emailAddress,
),
new InputDecorator(
decoration: const InputDecoration(
icon: const Icon(Icons.color_lens),
labelText: 'Color',
),
isEmpty: _color == '',
child: new DropdownButtonHideUnderline(
child: new DropdownButton<String>(
value: _color,
isDense: true,
onChanged: (String newValue) {
setState(() {
_color = newValue;
});
},
items: _colors.map((String value) {
return new DropdownMenuItem<String>(
value: value,
child: new Text(value),
);
}).toList(),
),
),
),
new Container(
padding: const EdgeInsets.only(left: 40.0, top: 20.0),
child: new RaisedButton(
child: const Text('Submit'),
onPressed: null,
)),
],
)
)
);
}

List<ExpansionPanelRow> getRows() {
return <ExpansionPanelRow>[
new ExpansionPanelRow(
false,
'Schools',
new Padding(
padding: new EdgeInsets.all(20.0),
child: interviewDataForm()
),
new Icon(
Icons.call,
size: 18.0,
color: Color(0xFF42A5F5)
)
),
new ExpansionPanelRow(
false,
'Schools',
new Padding(
padding: new EdgeInsets.all(20.0),
child: new Column(children: <Widget>[])
),
new Icon(
Icons.call,
size: 18.0,
color: Color(0xFF42A5F5)
)
),
];
}

ListView listCriteria;

Widget build(BuildContext context) {
listCriteria = new ListView(
children: [
new Padding(
padding: new EdgeInsets.all(10.0),
child: new ExpansionPanelList(
expansionCallback: (int index, bool isExpanded) {
setState(() {
getRows()[index].isExpanded = !getRows()[index].isExpanded;
});
},
children: getRows().map((ExpansionPanelRow row) {
return new ExpansionPanel(
headerBuilder: (BuildContext context, bool isExpanded) {
return new ListTile(
leading: row.icon,
title: new Text(
row.header,
textAlign: TextAlign.left,
style: new TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.w400,
),
));
},
isExpanded: row.isExpanded,
body: row.body,
);
}).toList(),
),
)
],
);

Scaffold scaffold = new Scaffold(
appBar: new AppBar(
title: new Text("App"),
),
body: listCriteria,
persistentFooterButtons: <Widget>[
new ButtonBar(children: <Widget>[
new FlatButton(
color: Colors.blue,
onPressed: null,
child: new Text(
'Add',
textAlign: TextAlign.left,
style: new TextStyle(fontWeight: FontWeight.bold),
),
)
])
],
);
return scaffold;
}
}

在哪个Widget中定义高度比较好?我应该在所有 Widget 中定义高度吗?

最佳答案

如错误所述:

If this widget is always nested in a scrollable widget there is no need to use a viewport because there will always be enough vertical space for the children. In this case, consider using a Column instead. Otherwise, consider using the "shrinkWrap" property (or a ShrinkWrappingViewport) to size the height of the viewport to the sum of the heights of its children.

要解决此错误,请添加 shrinkWrap: true :

 Widget interviewDataForm() {
return new SafeArea(
top: false,
bottom: false,
child: Form(
key: _formKey,
autovalidate: true,
child: new ListView(
shrinkWrap: true,
padding: const EdgeInsets.symmetric(horizontal: 16.0),
children: <Widget>[

关于android - Flutter - 如何使用包含表单的可扩展面板构建 ListView ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51752235/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com