我有一个TextField(不是Text)小部件,必须保持在一行上。如果要输入的文本对于TextField框太大,我想减小它的字体大小,即,如果溢出则缩小它。我怎样才能做到这一点?
我已经在有状态组件中编写了这样的代码
if (textLength < 32) { newAutoTextVM.fontSize = 35.0; } else if (textLength < 42) { newAutoTextVM.fontSize = 25.0;
在视图中
fontSize: 25.0,
但是它不是很智能,不能适应大小调整,而且因为字体大小不是等宽的(快递等),所以不同的字符会占用不同的空间。
使用a TextPainter来计算文本的宽度。使用a GlobalKey获取小部件的大小(使用A LayoutBuilder可能更好地处理屏幕旋转)。
TextPainter
GlobalKey
LayoutBuilder
import 'package:flutter/material.dart'; main() => runApp(MaterialApp(home: Home())); class Home extends StatefulWidget { @override _HomeState createState() => _HomeState(); } const textFieldPadding = EdgeInsets.all(8.0); const textFieldTextStyle = TextStyle(fontSize: 30.0); class _HomeState extends State<Home> { final TextEditingController _controller = TextEditingController(); final GlobalKey _textFieldKey = GlobalKey(); double _textWidth = 0.0; double _fontSize = textFieldTextStyle.fontSize; @override void initState() { super.initState(); _controller.addListener(_onTextChanged); } void _onTextChanged() { // substract text field padding to get available space final inputWidth = _textFieldKey.currentContext.size.width - textFieldPadding.horizontal; // calculate width of text using text painter final textPainter = TextPainter( textDirection: TextDirection.ltr, text: TextSpan( text: _controller.text, style: textFieldTextStyle, ), ); textPainter.layout(); var textWidth = textPainter.width; var fontSize = textFieldTextStyle.fontSize; // not really efficient and doesn't find the perfect size, but you got all you need! while (textWidth > inputWidth && fontSize > 1.0) { fontSize -= 0.5; textPainter.text = TextSpan( text: _controller.text, style: textFieldTextStyle.copyWith(fontSize: fontSize), ); textPainter.layout(); textWidth = textPainter.width; } setState(() { _textWidth = textPainter.width; _fontSize = fontSize; }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Autosize TextField'), ), body: Padding( padding: EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: <Widget>[ TextField( key: _textFieldKey, controller: _controller, decoration: InputDecoration( border: InputBorder.none, fillColor: Colors.orange, filled: true, contentPadding: textFieldPadding, ), style: textFieldTextStyle.copyWith(fontSize: _fontSize), ), Text('Text width:'), Container( padding: textFieldPadding, color: Colors.orange, child: Row( children: <Widget>[ Container(width: _textWidth, height: 20.0, color: Colors.blue), ], ), ) ], ), ), ); } }