代码之家  ›  专栏  ›  技术社区  ›  atreeon

颤振文本域-如果输入的文本溢出,如何缩小字体

  •  0
  • atreeon  · 技术社区  · 6 年前

    我有一个文本域(不是文本)小部件,必须保持在一行。我想减少它的字体大小,如果输入的文本太大的文本字段框,即缩小它,如果它溢出。我该怎么做?

    我在一个有状态的组件中写了一些这样的代码

    if (textLength < 32) {
      newAutoTextVM.fontSize = 35.0;
    } else if (textLength < 42) {
      newAutoTextVM.fontSize = 25.0;
    

    在视野中

    fontSize: 25.0,
    

    但是它不是很智能,它不能处理大小调整,而且,因为字体大小不是等距的(courier等),不同的字符占用不同的空间。

    2 回复  |  直到 6 年前
        1
  •  1
  •   boformer    6 年前

    使用 TextPainter 计算文本的宽度。使用 GlobalKey 获取小部件的大小(A 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),
                    ],
                  ),
                )
              ],
            ),
          ),
        );
      }
    }
    
        2
  •  -1
  •   Andrea Grippi    6 年前

    我已经搜索了这些文档,找到了一些可以在您帮助下找到的解决方案:

    • 看看这位官员 ̶d̶o̶c̶s̶ [1],尤其是这些属性:maxLines、overflow和softWrap(这些是文本框属性,不是文本字段)
    • 看一看 this 他们建议用灵活的小部件包装文本框/文本框

    根据代码的其余部分,这些解决方案中的一个可能更好,请尝试调整。
    希望有帮助。