【问题标题】:How to check if Flutter Text widget was overflowed如何检查 Flutter Text 小部件是否溢出
【发布时间】:2018-12-09 10:02:56
【问题描述】:

我有一个 Text 小部件,如果它超过一定大小,可以截断:

ConstrainedBox(
  constraints: BoxConstraints(maxHeight: 50.0),
  child: Text(
    widget.review,
    overflow: TextOverflow.ellipsis,
  )
);

或最大行数:

RichText(
  maxLines: 2,
  overflow: TextOverflow.ellipsis,
  text: TextSpan(
    style: TextStyle(color: Colors.black),
    text: widget.review,
  ));

我的目标是让文本只有在发生溢出时才可展开。是否有适当的方法来检查文本是否溢出?

我尝试过的

我发现在 RichText 中有一个 RenderParagraph renderObject ,它有一个私有属性 TextPainter _textPainter 有一个 bool didExceedMaxLines

简而言之,我只需要访问richText.renderObject._textPainter.didExceedMaxLines,但正如您所见,它是私有的,带有下划线。

【问题讨论】:

    标签: dart flutter


    【解决方案1】:

    我找到了一种方法。完整代码如下,简而言之:

    1. 使用 LayoutBuilder 来确定我们有多少空间。
    2. 使用 TextPainter 模拟空间内文本的渲染。

    这是完整的演示应用:

    import 'package:flutter/material.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Text Overflow Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: Scaffold(
            appBar: AppBar(title: Text("DEMO")),
            body: TextOverflowDemo(),
          ),
        );
      }
    }
    
    class TextOverflowDemo extends StatefulWidget {
      @override
      _EditorState createState() => _EditorState();
    }
    
    class _EditorState extends State<TextOverflowDemo> {
      var controller = TextEditingController();
    
      @override
      void initState() {
        controller.addListener(() {
          setState(() {
            mytext = controller.text;
          });
        });
        controller.text = "This is a long overflowing text!!!";
        super.initState();
      }
    
      @override
      void dispose() {
        controller.dispose();
        super.dispose();
      }
    
      String mytext = "";
    
      @override
      Widget build(BuildContext context) {
        int maxLines = 1;
        double fontSize = 30.0;
    
        return Padding(
          padding: const EdgeInsets.all(12.0),
          child: Column(
            children: <Widget>[
              LayoutBuilder(builder: (context, size) {
                // Build the textspan
                var span = TextSpan(
                  text: mytext,
                  style: TextStyle(fontSize: fontSize),
                );
    
                // Use a textpainter to determine if it will exceed max lines
                var tp = TextPainter(
                  maxLines: maxLines,
                  textAlign: TextAlign.left,
                  textDirection: TextDirection.ltr,
                  text: span,
                );
    
                // trigger it to layout
                tp.layout(maxWidth: size.maxWidth);
    
                // whether the text overflowed or not
                var exceeded = tp.didExceedMaxLines;
    
                return Column(children: <Widget>[
                  Text.rich(
                    span,
                    overflow: TextOverflow.ellipsis,
                    maxLines: maxLines,
                  ),
                  Text(exceeded ? "Overflowed!" : "Not overflowed yet.")
                ]);
              }),
              TextField(
                controller: controller,
              ),
            ],
          ),
        );
      }
    }
    

    【讨论】:

      【解决方案2】:

      如果文本是否溢出,有一种更短的方法可以得到答案。你只需要定义 textStyle 并从这个方法中得到答案

      bool hasTextOverflow(
        String text, 
        TextStyle style, 
        {double minWidth = 0, 
             double maxWidth = double.infinity, 
             int maxLines = 2
        }) {
        final TextPainter textPainter = TextPainter(
          text: TextSpan(text: text, style: style),
          maxLines: maxLines,
          textDirection: TextDirection.ltr,
        )..layout(minWidth: minWidth, maxWidth: maxWidth);
        return textPainter.didExceedMaxLines;
      }
      

      【讨论】:

        【解决方案3】:

        您可以在pub.dev 使用颤振插件auto_size_text。 当文本溢出时,您可以设置一些小部件出现。

        int maxLines = 3;
        String caption = 'Your caption is here';
        return AutoSizeText(
            caption,
            maxLines: maxLines,
            style: TextStyle(fontSize: 20),
            minFontSize: 15,
            overflowReplacement: Column( // This widget will be replaced. 
            crossAxisAlignment: CrossAxisAlignment.start,
            children: <Widget>[
              Text(
                caption,
                maxLines: maxLines,
                overflow: TextOverflow.ellipsis,
              ),
              Text(
                "Show more",
                style: TextStyle(color: PrimaryColor.kGrey),
              )
            ],
          ),
        );
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-08-15
          • 2020-07-22
          • 1970-01-01
          • 2022-09-27
          • 2019-01-17
          • 2021-08-23
          • 2020-08-21
          相关资源
          最近更新 更多