Dans le flutter, TextField n'a pas de largeur intrinsèque; il ne sait comment se dimensionner que sur toute la largeur de son conteneur parent. Comment définir la largeur sur la largeur du texte contenu.
J'ai essayé de placer le TextField dans un conteneur
Comme indiqué ici Comment mettre à jour la hauteur et la largeur de Flutter TextField? p >
new Container( width: 100.0, child: new TextField() )
Je m'attends à ce que la largeur du TextField corresponde à la largeur du texte qu'il contient. Le TextField doit s'élargir au fur et à mesure que le texte est saisi, et se rétrécir lorsque le texte est supprimé.
3 Réponses :
J'ai pu obtenir le résultat attendu en utilisant un TextPainter pour calculer la largeur souhaitée du texte. J'ai ensuite utilisé cette largeur comme largeur du Container contenant le TextField .
N'oubliez pas d'appeler setState () dans votre TextFields méthode onChanged . Cela indique au widget de se redessiner, ce qui oblige TextField à s'adapter à la nouvelle largeur de son contenu.
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(() {});
},
),
);
}
}
C'est bien ! Merci !
Quand il y a plus de lettres, il ne se développe plus correctement.
J'ai pu résoudre ce problème pour que j'ajoute: decoration: InputDecoration (contentPadding: EdgeInsets.only (left: 0, right: -5),) au TextField.
@MichaelBerger que la valeur EdgeInset dépend de la taille de la police, de la famille de polices et d'autres paramètres. S'il vous plaît, vérifiez ma réponse ci-dessous pour une solution qui fonctionne avec toutes les tailles de police et les visages de police
J'ai légèrement modifié la réponse de SteveM pour corriger le bogue lorsque le widget ne se développe pas correctement. Nous devons respecter ces deux petites choses lors du calcul de la largeur du widget:
TextField fusionne le paramètre textStyle donné et le TextStyle du thème actuel. Cela doit également être fait dans un widget personnalisé: 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(() {});
},
),
);
}
}
cursorWidth de TextField doit être pris en compte dans les calculs de largeur du widget. Puisqu'il n'y a aucun moyen d'obtenir la largeur du curseur par défaut de la classe TextField , j'ai vérifié son code et ajouté une nouvelle constante à la classe FitsTextField . N'oubliez pas de le transmettre au constructeur de TextField : final textWidth = max(widget.minWidth, tp.width + _CURSOR_WIDTH);
// When building a TextField:
child: TextField(
cursorWidth: _CURSOR_WIDTH,
Code complet:
final ThemeData themeData = Theme.of(context); final TextStyle style = themeData.textTheme.subtitle1.merge(textStyle);
Flutter a IntrinsicWidth pour faire le calcul pour vous. Enveloppez simplement votre TextField ou TextFormField comme suit:
IntrinsicWidth(child: TextField())
Si le TextFormField est vide, il affiche un widget affreux et étroit.
Voici un joli package qui résume une solution à ce problème. pub.dev/packages/fitted_text_field_container