In flutter, TextField doesn't have an intrinsic width; it only knows how to size itself to the full width of its parent container. How do I set the width to the width of the contained text.
I tried putting the TextField inside a container
As outlined here
How to update flutter TextField's height and width?
new Container(
width: 100.0,
child: new TextField()
)
I expect the width of the TextField to match the width of the text it contains. The TextField should grow wider as text is typed, and shrink narrower as text is deleted.
I was able to achieve the expected result by using a TextPainter
to compute the desired width of the text. I then used that width as the width of the Container
containing the TextField
.
Remember to call setState()
in your TextFields onChanged
method. This tells the widget to redraw itself causing the TextField to adjust to the new width of its content.
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(() {});
},
),
);
}
}