我收到一个渲染异常,我不知道如何解决。我正在尝试创建一个有 3 行的列。
行 [图像]
行 [文本字段]
行 [按钮]
这是我构建容器的代码:
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;
}
和我的文本容器的构建AppEntryRow代码
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更改为仅文本字段
Widget buildAppEntryRow2(BuildContext context) {
return new TextField(
decoration: const InputDecoration(helperText: "Enter App ID"),
style: Theme.of(context).textTheme.body1,
);
}
我不再得到例外。Row 实现缺少什么导致它无法计算该行的大小?
(我假设您正在使用Row
,因为您希望将来将其他小部件放在TextField
旁边。
Row
小组件想要确定其非灵活子项的固有大小,以便知道为灵活子项保留了多少空间。但是,TextField
没有固有宽度;它只知道如何将自己的大小调整到其父容器的整个宽度。尝试将其包装在Flexible
或Expanded
中,以告诉Row
您希望TextField
占用剩余空间:
new Row(
children: <Widget>[
new Flexible(
child: new TextField(
decoration: const InputDecoration(helperText: "Enter App ID"),
style: Theme.of(context).textTheme.body1,
),
),
],
),
你得到这个错误是因为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(), ], )
您应该使用"灵活"在行内使用文本字段。
new Row(
children: <Widget>[
new Text("hi there"),
new Container(
child:new Flexible(
child: new TextField( ),
),//flexible
),//container
],//widget
),//row
解决方案是将您的Text()
包装在以下小部件之一中: 要么Expanded
,要么Flexible
.因此,使用扩展的代码将如下所示:
Expanded(
child: TextField(
decoration: InputDecoration(
hintText: "Demo Text",
hintStyle: TextStyle(fontWeight: FontWeight.w300, color: Colors.red)
),
),
),
正如设拉子@Asif提到的,我遇到了同样的问题,并通过在柔性中包装列来解决这个问题,就像这样,,
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,
),
));
}
}
TextField
的InputDecoration
在放置在Row
内时会导致无限宽度问题。Flutter 在InputDecoration
约束属性文档中对此进行了解释:
通常,装饰器将填充给定的水平空间。如果为 null,则将使用环境
ThemeData.inputDecorationTheme
的InputDecorationTheme.constraints
。如果为 null,则装饰器将根据文本大小使用默认高度填充可用宽度。
因此,好消息是可以限制TextField
的宽度,而无需使用周围的小部件,例如Expanded
.只需向TextField
小组件使用的InputDecoration
的constraints
参数提供BoxConstraints
实例:
const TextField(
decoration: InputDecoration(
constraints: BoxConstraints.tightFor(
width: 200,
),
),
)
如上面的 Flutter 文档所述,可以使用带有ThemeData
的Theme
一次将一组约束应用于多个小部件,该指定具有所需约束的InputDecorationTheme
,以便从Theme
继承和使用。
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))),
),
),
),
],
),
我遇到了同样的问题。
如果需要,可以使用表格小部件来避免文本字段的此类问题
一个简单的解决方案是将您的Text()
包装在Container()
中。 因此,您的代码将如下所示:
Container(
child: TextField()
)
在这里,您还可以获得容器的宽度和高度属性,以调整文本字段的外观。如果要将文本字段包装在容器内,则无需使用Flexible
。
如果您希望 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 对这个小部件的看法。
创建一个小组件,该构件将其子项的大小调整为子项的固有宽度。 这个类相对昂贵。尽可能避免使用它。
最好的解决方案是使用Absouluts空间值
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()),
],
),