Flutter TextField的宽度应与包含的文本的宽度相匹配。
Flutter TextField的宽度应与包含的文本的宽度相匹配。
在flutter中,TextField没有固有的宽度;它只知道如何根据其父容器的宽度自适应大小。我应该如何将宽度设置为所包含文本的宽度呢?
我尝试将TextField放在一个容器中,如下所述:
How to update flutter TextField's height and width?
new Container(
width: 100.0,
child: new TextField()
)
我期望TextField的宽度与其包含的文本的宽度相匹配。当输入文本时,TextField应该变得更宽,当删除文本时,TextField应该变得更窄。
问题出现的原因是,当使用空的TextFormField时,它会显示一个狭窄的小部件。解决方法是使用IntrinsicWidth包裹TextField或TextFormField,或者使用Container添加一个具有最小宽度的BoxConstraints。
代码示例:
IntrinsicWidth(child: TextField())
或者
Container(constraints: BoxConstraints(minWidth: 100),child: TextField())
另外,你也可以通过传递一个提示文本来避免这个问题。
然而,如果你在使用上述方法后仍然没有看到效果,可能是因为你在父级部件中使用了ListTile,并将文本字段左对齐,并将其限制在一个SizedBox中。
问题的出现原因是Flutter的TextField组件的宽度没有自适应文本内容的宽度。解决方法是使用TextPainter计算文本的宽度,并将该宽度作为包含TextField的Container的宽度。同时,在TextField的onChanged方法中调用setState()方法,告诉组件重新绘制自身以调整TextField的宽度。
以下是解决该问题的代码示例:
import 'package:flutter/material.dart';
class FitTextField extends StatefulWidget {
final String initialValue;
final double minWidth;
const FitTextField({Key key, this.initialValue, this.minWidth: 30}): super(key: key);
@override
State
}
class FitTextFieldState extends State
TextEditingController txt = TextEditingController();
// We will use this text style for the TextPainter used to calculate the width
// and for the TextField so that we calculate the correct size for the text
// we are actually displaying
TextStyle textStyle = TextStyle(color: Colors.grey[600]);
@override
void initState() {
super.initState();
// Set the text in the TextField to our initialValue
txt.text = widget.initialValue;
}
@override
Widget build(BuildContext context) {
// Use TextPainter to calculate the width of our text
TextSpan ts = new TextSpan(style: textStyle, text: txt.text);
TextPainter tp = new TextPainter(text: ts, textDirection: TextDirection.ltr);
tp.layout();
var textWidth = tp.width; // We will use this width for the container wrapping our TextField
// Enforce a minimum width
if ( textWidth < widget.minWidth ) {
textWidth = widget.minWidth;
}
return Container(
width: textWidth,
child: TextField(
style: textStyle,
controller: txt,
onChanged: (text) {
// Tells the framework to redraw the widget
// The widget will redraw with a new width
setState(() {});
},
),
);
}
}
感谢这位开发者的回答!当文本较长时,TextField无法正确地展开。为了解决这个问题,我添加了decoration: InputDecoration(contentPadding: EdgeInsets.only(left:0,right:-5),)
到TextField中。其中,EdgeInsets的值取决于字体大小、字体系列和其他参数。请查看下面的答案,以获取适用于所有字体大小和字体系列的解决方案。
Flutter中的TextField组件的宽度应该与包含的文本的宽度相匹配。
在计算TextField组件的宽度时,我们需要考虑以下两个小细节:
1. TextField会合并给定的textStyle参数和当前主题的TextStyle。在自定义组件中,我们也需要这样做:
final ThemeData themeData = Theme.of(context);
final TextStyle style = themeData.textTheme.subtitle1.merge(textStyle);
2. TextField的cursorWidth属性也必须包含在组件的宽度计算中。由于无法从TextField类中获取默认的光标宽度,我检查了它的代码,并在FitTextField类中添加了一个新的常量。别忘了将它传递给TextField的构造函数:
final textWidth = max(widget.minWidth, tp.width + _CURSOR_WIDTH);
// 当构建TextField时:
child: TextField(
cursorWidth: _CURSOR_WIDTH,
完整代码如下:
import 'dart:math';
import 'package:flutter/material.dart';
class FitTextField extends StatefulWidget {
final String initialValue;
final double minWidth;
const FitTextField({
Key key,
this.initialValue,
this.minWidth: 30,
}) : super(key: key);
State
}
class FitTextFieldState extends State
// 2.0是TextField类的默认值
static const _CURSOR_WIDTH = 2.0;
TextEditingController txt = TextEditingController();
// 我们将使用这个文本样式来计算宽度的TextPainter和TextField,以便我们计算出我们实际显示的文本的正确尺寸
TextStyle textStyle = TextStyle(
color: Colors.grey[600],
fontSize: 16,
);
initState() {
super.initState();
// 将TextField中的文本设置为我们的initialValue
txt.text = widget.initialValue;
}
Widget build(BuildContext context) {
// TextField会将给定的textStyle与当前主题的文本样式合并,我们也需要这样做来获取最终的TextStyle
final ThemeData themeData = Theme.of(context);
final TextStyle style = themeData.textTheme.subtitle1.merge(textStyle);
// 使用TextPainter来计算文本的宽度
TextSpan ts = new TextSpan(style: style, text: txt.text);
TextPainter tp = new TextPainter(
text: ts,
textDirection: TextDirection.ltr,
);
tp.layout();
// 强制最小宽度
final textWidth = max(widget.minWidth, tp.width + _CURSOR_WIDTH);
return Container(
width: textWidth,
child: TextField(
cursorWidth: _CURSOR_WIDTH,
style: style,
controller: txt,
onChanged: (text) {
// 重新绘制组件
setState(() {});
},
),
);
}
}
以上就是解决Flutter中TextField宽度应该与文本宽度相匹配的问题的原因和解决方法。