Row 内的 TextField 导致布局异常:无法计算大小
TextField inside of Row causes layout exception: Unable to calculate size
我遇到了一个渲染异常,我不知道如何修复。我正在尝试创建一个包含 3 行的列。
行[图片]
行[TextField]
行[按钮]
这是我构建容器的代码:
Container buildEnterAppContainer(BuildContext context) {
var container = new Container(
padding: const EdgeInsets.all(8.0),
child: new Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
buildImageRow(context),
buildAppEntryRow(context),
buildButtonRow(context)
],
),
);
return container;
}
和我的文本容器的 buildAppEntryRow 代码
Widget buildAppEntryRow(BuildContext context) {
return new Row(
children: <Widget>[
new TextField(
decoration: const InputDecoration(helperText: "Enter App ID"),
style: Theme.of(context).textTheme.body1,
)
],
);
}
当我 运行 我得到以下异常:
I/flutter ( 7674): BoxConstraints forces an infinite width.
I/flutter ( 7674): These invalid constraints were provided to RenderStack's layout() function by the following
I/flutter ( 7674): function, which probably computed the invalid constraints in question:
I/flutter ( 7674): RenderConstrainedBox.performLayout (package:flutter/src/rendering/proxy_box.dart:256:13)
I/flutter ( 7674): The offending constraints were:
I/flutter ( 7674): BoxConstraints(w=Infinity, 0.0<=h<=Infinity)
如果我像这样将 buildAppEntryRow 更改为一个 TextField
Widget buildAppEntryRow2(BuildContext context) {
return new TextField(
decoration: const InputDecoration(helperText: "Enter App ID"),
style: Theme.of(context).textTheme.body1,
);
}
我不再遇到异常。 Row 实现中缺少什么导致它无法计算该行的大小?
(我假设您使用的是 Row
,因为您希望将来在 TextField
旁边放置其他小部件。)
Row
小部件想要确定其非灵活子项的固有大小,以便它知道它为灵活子项留下了多少 space。但是,TextField
没有固有宽度;它只知道如何将自己的大小调整到其父容器的整个宽度。尝试将其包装在 Flexible
或 Expanded
中以告诉 Row
您希望 TextField
占用剩余的 space:
new Row(
children: <Widget>[
new Flexible(
child: new TextField(
decoration: const InputDecoration(helperText: "Enter App ID"),
style: Theme.of(context).textTheme.body1,
),
),
],
),
您应该使用 Flexible 来在行内使用文本字段。
new Row(
children: <Widget>[
new Text("hi there"),
new Container(
child:new Flexible(
child: new TextField( ),
),//flexible
),//container
],//widget
),//row
一个简单的解决方案是将 Text()
包裹在 Container()
中。
所以,你的代码将是这样的:
Container(
child: TextField()
)
在这里您还可以获取容器的宽度和高度属性来调整文本字段的外观。如果您将文本字段包装在容器中,则无需使用 Flexible
。
正如@Asif Shiraz 提到的,我遇到了同样的问题,并通过在灵活的包装柱中解决了这个问题,这里是这样的,
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new Scaffold(
body: Row(
children: <Widget>[
Flexible(
child: Column(
children: <Widget>[
Container(
child: TextField(),
)
//container
],
))
],
mainAxisAlignment: MainAxisAlignment.spaceBetween,
),
));
}
}
解决方案是将您的 Text()
包装在以下小部件之一中:
要么Expanded
or Flexible
。因此,您使用 Expanded 的代码将类似于:
Expanded(
child: TextField(
decoration: InputDecoration(
hintText: "Demo Text",
hintStyle: TextStyle(fontWeight: FontWeight.w300, color: Colors.red)
),
),
),
你得到这个错误是因为TextField
在水平方向扩展,Row
也是如此,所以我们需要限制TextField
的宽度,有很多方法可以做到它。
使用Expanded
Row(
children: <Widget>[
Expanded(child: TextField()),
OtherWidget(),
],
)
使用Flexible
Row(
children: <Widget>[
Flexible(child: TextField()),
OtherWidget(),
],
)
将其包裹在Container
或SizedBox
中并提供width
Row(
children: <Widget>[
SizedBox(width: 100, child: TextField()),
OtherWidget(),
],
)
我遇到了同样的问题
如果需要,您可以使用 Table 小部件来避免 TextField[=10= 出现此类问题]
Row(
children: [
Expanded(
flex: 1,
child: Padding(
padding: EdgeInsets.only(left: 5.0,right: 5.0),
child: TextFormField(
controller: commentController,
validator: (String value){
if(value.isEmpty){
// ignore: missing_return
return 'Comment cannot be blank.';
}
},
decoration: InputDecoration(
labelText: "Comment",
labelStyle: TextStyle(
fontFamily: 'Montserrat',
fontWeight: FontWeight.bold,
color: Colors.grey),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.green))),
),
),
),
],
),
如果您希望 TextField 根据其内容水平调整自身大小,则可以使用 IntrinsicWidth 小部件将其包装。
Row(
children: [
Text("From"),
SizedBox(width: 10,),
IntrinsicWidth(child: TextField(
textAlignVertical: TextAlignVertical.center,
decoration: InputDecoration(
hintText: "Start Date Start Date Start Date",
hintStyle: TextStyle(color: Colour.pBlue, fontSize: 14),
border: InputBorder.none,
),
),),
SizedBox(width: 10,),
Text("To"),
SizedBox(width: 10,),
IntrinsicWidth(child: IntrinsicWidth(child: TextField(
textAlignVertical: TextAlignVertical.center,
decoration: InputDecoration(
hintText: "End Date",
hintStyle: TextStyle(color: Colour.pBlue, fontSize: 14),
border: InputBorder.none,
),
),)),
],
)
但在您的代码中使用它之前,请确保了解 Flutter 对这个小部件的评价。
Creates a widget that sizes its child to the child's intrinsic width.
This class is relatively expensive. Avoid using it where possible.
the best solution is with absouluts space values
Row(
children: <Widget>[
SizedBox(
width: MediaQuery.of(context).size.width * 0.3,
child: _telephonePrefixInput()
),
SizedBox(width: MediaQuery.of(context).size.width * 0.02),
Expanded(child: _telephoneInput()),
],
),
TextField
的 InputDecoration
放在 Row
中时会导致无限宽度问题。 Flutter 在 InputDecoration
constraints property 文档中对此进行了解释:
Typically the decorator will fill the horizontal space it is given. ... If null, then the ambient ThemeData.inputDecorationTheme
's InputDecorationTheme.constraints
will be used. If that is null then the decorator will fill the available width with a default height based on text size.
所以,好消息是 TextField
的宽度可以在不使用像 Expanded
这样的周围小部件的情况下被限制。只需将 BoxConstraints
的实例提供给 TextField
小部件使用的 InputDecoration
的 constraints
参数:
const TextField(
decoration: InputDecoration(
constraints: BoxConstraints.tightFor(
width: 200,
),
),
)
如上面的 Flutter 文档中所述,可以通过使用 Theme
和 ThemeData
指定 InputDecorationTheme
来一次将一组约束应用于多个小部件Theme
的后代小部件继承和使用所需的约束。
我遇到了一个渲染异常,我不知道如何修复。我正在尝试创建一个包含 3 行的列。
行[图片]
行[TextField]
行[按钮]
这是我构建容器的代码:
Container buildEnterAppContainer(BuildContext context) {
var container = new Container(
padding: const EdgeInsets.all(8.0),
child: new Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
buildImageRow(context),
buildAppEntryRow(context),
buildButtonRow(context)
],
),
);
return container;
}
和我的文本容器的 buildAppEntryRow 代码
Widget buildAppEntryRow(BuildContext context) {
return new Row(
children: <Widget>[
new TextField(
decoration: const InputDecoration(helperText: "Enter App ID"),
style: Theme.of(context).textTheme.body1,
)
],
);
}
当我 运行 我得到以下异常:
I/flutter ( 7674): BoxConstraints forces an infinite width.
I/flutter ( 7674): These invalid constraints were provided to RenderStack's layout() function by the following
I/flutter ( 7674): function, which probably computed the invalid constraints in question:
I/flutter ( 7674): RenderConstrainedBox.performLayout (package:flutter/src/rendering/proxy_box.dart:256:13)
I/flutter ( 7674): The offending constraints were:
I/flutter ( 7674): BoxConstraints(w=Infinity, 0.0<=h<=Infinity)
如果我像这样将 buildAppEntryRow 更改为一个 TextField
Widget buildAppEntryRow2(BuildContext context) {
return new TextField(
decoration: const InputDecoration(helperText: "Enter App ID"),
style: Theme.of(context).textTheme.body1,
);
}
我不再遇到异常。 Row 实现中缺少什么导致它无法计算该行的大小?
(我假设您使用的是 Row
,因为您希望将来在 TextField
旁边放置其他小部件。)
Row
小部件想要确定其非灵活子项的固有大小,以便它知道它为灵活子项留下了多少 space。但是,TextField
没有固有宽度;它只知道如何将自己的大小调整到其父容器的整个宽度。尝试将其包装在 Flexible
或 Expanded
中以告诉 Row
您希望 TextField
占用剩余的 space:
new Row(
children: <Widget>[
new Flexible(
child: new TextField(
decoration: const InputDecoration(helperText: "Enter App ID"),
style: Theme.of(context).textTheme.body1,
),
),
],
),
您应该使用 Flexible 来在行内使用文本字段。
new Row(
children: <Widget>[
new Text("hi there"),
new Container(
child:new Flexible(
child: new TextField( ),
),//flexible
),//container
],//widget
),//row
一个简单的解决方案是将 Text()
包裹在 Container()
中。
所以,你的代码将是这样的:
Container(
child: TextField()
)
在这里您还可以获取容器的宽度和高度属性来调整文本字段的外观。如果您将文本字段包装在容器中,则无需使用 Flexible
。
正如@Asif Shiraz 提到的,我遇到了同样的问题,并通过在灵活的包装柱中解决了这个问题,这里是这样的,
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new Scaffold(
body: Row(
children: <Widget>[
Flexible(
child: Column(
children: <Widget>[
Container(
child: TextField(),
)
//container
],
))
],
mainAxisAlignment: MainAxisAlignment.spaceBetween,
),
));
}
}
解决方案是将您的 Text()
包装在以下小部件之一中:
要么Expanded
or Flexible
。因此,您使用 Expanded 的代码将类似于:
Expanded(
child: TextField(
decoration: InputDecoration(
hintText: "Demo Text",
hintStyle: TextStyle(fontWeight: FontWeight.w300, color: Colors.red)
),
),
),
你得到这个错误是因为TextField
在水平方向扩展,Row
也是如此,所以我们需要限制TextField
的宽度,有很多方法可以做到它。
使用
Expanded
Row( children: <Widget>[ Expanded(child: TextField()), OtherWidget(), ], )
使用
Flexible
Row( children: <Widget>[ Flexible(child: TextField()), OtherWidget(), ], )
将其包裹在
Container
或SizedBox
中并提供width
Row( children: <Widget>[ SizedBox(width: 100, child: TextField()), OtherWidget(), ], )
我遇到了同样的问题
如果需要,您可以使用 Table 小部件来避免 TextField[=10= 出现此类问题]
Row(
children: [
Expanded(
flex: 1,
child: Padding(
padding: EdgeInsets.only(left: 5.0,right: 5.0),
child: TextFormField(
controller: commentController,
validator: (String value){
if(value.isEmpty){
// ignore: missing_return
return 'Comment cannot be blank.';
}
},
decoration: InputDecoration(
labelText: "Comment",
labelStyle: TextStyle(
fontFamily: 'Montserrat',
fontWeight: FontWeight.bold,
color: Colors.grey),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.green))),
),
),
),
],
),
如果您希望 TextField 根据其内容水平调整自身大小,则可以使用 IntrinsicWidth 小部件将其包装。
Row(
children: [
Text("From"),
SizedBox(width: 10,),
IntrinsicWidth(child: TextField(
textAlignVertical: TextAlignVertical.center,
decoration: InputDecoration(
hintText: "Start Date Start Date Start Date",
hintStyle: TextStyle(color: Colour.pBlue, fontSize: 14),
border: InputBorder.none,
),
),),
SizedBox(width: 10,),
Text("To"),
SizedBox(width: 10,),
IntrinsicWidth(child: IntrinsicWidth(child: TextField(
textAlignVertical: TextAlignVertical.center,
decoration: InputDecoration(
hintText: "End Date",
hintStyle: TextStyle(color: Colour.pBlue, fontSize: 14),
border: InputBorder.none,
),
),)),
],
)
但在您的代码中使用它之前,请确保了解 Flutter 对这个小部件的评价。
Creates a widget that sizes its child to the child's intrinsic width. This class is relatively expensive. Avoid using it where possible.
the best solution is with absouluts space values
Row(
children: <Widget>[
SizedBox(
width: MediaQuery.of(context).size.width * 0.3,
child: _telephonePrefixInput()
),
SizedBox(width: MediaQuery.of(context).size.width * 0.02),
Expanded(child: _telephoneInput()),
],
),
TextField
的 InputDecoration
放在 Row
中时会导致无限宽度问题。 Flutter 在 InputDecoration
constraints property 文档中对此进行了解释:
Typically the decorator will fill the horizontal space it is given. ... If null, then the ambient
ThemeData.inputDecorationTheme
'sInputDecorationTheme.constraints
will be used. If that is null then the decorator will fill the available width with a default height based on text size.
所以,好消息是 TextField
的宽度可以在不使用像 Expanded
这样的周围小部件的情况下被限制。只需将 BoxConstraints
的实例提供给 TextField
小部件使用的 InputDecoration
的 constraints
参数:
const TextField(
decoration: InputDecoration(
constraints: BoxConstraints.tightFor(
width: 200,
),
),
)
如上面的 Flutter 文档中所述,可以通过使用 Theme
和 ThemeData
指定 InputDecorationTheme
来一次将一组约束应用于多个小部件Theme
的后代小部件继承和使用所需的约束。