Ste*_*veM 11 flutter flutter-layout
在 flutter 中,TextField 没有固有宽度;它只知道如何将自己的大小调整为其父容器的全宽。如何将宽度设置为包含文本的宽度。
我试着把 TextField 放在一个容器里
如此处概述 如何更新颤振 TextField 的高度和宽度?
new Container(
width: 100.0,
child: new TextField()
)
Run Code Online (Sandbox Code Playgroud)
我希望 TextField 的宽度与其包含的文本的宽度相匹配。TextField 应该在输入文本时变宽,并在删除文本时收缩变窄。
小智 20
Flutter 有IntrinsicWidth为你做计算。只需将您的TextField或包裹TextFormField在其中,如下所示:
IntrinsicWidth(child: TextField())
Run Code Online (Sandbox Code Playgroud)
通过使用 aTextPainter来计算所需的文本宽度,我能够达到预期的结果。然后我使用该宽度作为Container包含TextField.
请记住调用setState()您的 TextFieldsonChanged方法。这告诉小部件重新绘制自身,导致 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<StatefulWidget> createState() => new FitTextFieldState();
}
class FitTextFieldState extends State<FitTextField>{
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]);
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(() {});
},
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
我稍微修改了 SteveM 的答案,以修复小部件未正确扩展时的错误。在计算小部件的宽度时,我们应该考虑这两件小事:
TextField合并给定textStyle参数和当前主题的TextStyle. 这也必须在自定义小部件中完成:final ThemeData themeData = Theme.of(context);
final TextStyle style = themeData.textTheme.subtitle1.merge(textStyle);
Run Code Online (Sandbox Code Playgroud)
TextField必须将其cursorWidth纳入小部件的宽度计算中。由于无法从TextField类中获取默认光标宽度,因此我检查了其代码并向FitsTextField类添加了一个新常量。不要忘记将其传递给 的TextField构造函数:final textWidth = max(widget.minWidth, tp.width + _CURSOR_WIDTH);
// When building a TextField:
child: TextField(
cursorWidth: _CURSOR_WIDTH,
Run Code Online (Sandbox Code Playgroud)
完整代码:
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);
@override
State<StatefulWidget> createState() => new FitTextFieldState();
}
class FitTextFieldState extends State<FitTextField> {
// 2.0 is the default from TextField class
static const _CURSOR_WIDTH = 2.0;
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],
fontSize: 16,
);
initState() {
super.initState();
// Set the text in the TextField to our initialValue
txt.text = widget.initialValue;
}
@override
Widget build(BuildContext context) {
// TextField merges given textStyle with text style from current theme
// Do the same to get final TextStyle
final ThemeData themeData = Theme.of(context);
final TextStyle style = themeData.textTheme.subtitle1.merge(textStyle);
// Use TextPainter to calculate the width of our text
TextSpan ts = new TextSpan(style: style, text: txt.text);
TextPainter tp = new TextPainter(
text: ts,
textDirection: TextDirection.ltr,
);
tp.layout();
// Enforce a minimum width
final textWidth = max(widget.minWidth, tp.width + _CURSOR_WIDTH);
return Container(
width: textWidth,
child: TextField(
cursorWidth: _CURSOR_WIDTH,
style: style,
controller: txt,
onChanged: (text) {
// Redraw the widget
setState(() {});
},
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7511 次 |
| 最近记录: |