Flutter: Alternative text when truncated

262

I don't know if it's the most suitable way to achieve what you're trying to do but here's how we can do it :

Make a custom Widget which will take a list of String from greater value to lower so that it can check which value fit's in the available space.

class OverflowAwareText extends StatefulWidget {
  final List<String> alternativeTexts;
  OverflowAwareText({this.alternativeTexts});
  @override
  _OverflowAwareText createState() => _OverflowAwareText();
}

class _OverflowAwareText extends State<OverflowAwareText> {
  List<String> texts;
  int activeTextIndex = 0;

  @override
  void initState() {
    super.initState();
    texts = widget.alternativeTexts;
  }

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(builder: (context, size) {
      var textSpan = TextSpan(
        text: texts[activeTextIndex],
        style: TextStyle(fontSize: 42),
      );
      // Use a textpainter to determine if it will exceed max lines
      var textPainter = TextPainter(
        maxLines: 1,
        textAlign: TextAlign.left,
        textDirection: TextDirection.ltr,
        text: textSpan,
      )..layout(maxWidth: size.maxWidth);

      if (textPainter.didExceedMaxLines) {
        if (activeTextIndex != texts.length - 1) {
          WidgetsBinding.instance.addPostFrameCallback((t) {
            setState(() {
              activeTextIndex += 1;
            });
          });
        }
      }

      return Text.rich(
        textSpan,
        overflow: TextOverflow.ellipsis,
        maxLines: 1,
      );
    });
  }
}

Our OverflowAwareText takes a parameter alternativeTexts which is List<String>. You have to provide a list of Strings with larger to smaller values.

We can now use the OverflowAwareText :

@override
  Widget build(BuildContext context) {
    print('Printing from build method');
    return Scaffold(
      body: Center(
        child: Container(
          alignment: Alignment.center,
          height: 50,
          color: Colors.amber,
          child: OverflowAwareText(
            alternativeTexts: [
              'Kamala Devi Harris',
              'K. D. Harris',
              'K. Harris',
              'K. H'
            ],
          ),
        ),
      ),
    );
  }

We've wrapped the OverflowAwareText in a Container, so that we can check if the text is being changed or not when there is less space.

RESULT :

  • With no width in Container

enter image description here

  • With width = 330 in Container

enter image description here

  • With width = 180 in Container

enter image description here

With width = 100 in Container

enter image description here

Share:
262
derChris
Author by

derChris

Updated on December 26, 2022

Comments

  • derChris
    derChris over 1 year

    In some Text Widgets we display text which is getting truncated on some devices and we want to replace the text in this cases instead of truncating it.

    I.E. we display a name like "Kamala Devi Harris"

    When the name is too long for displaying we want to call a method and transform it to "Kamala D. Harris" and if that is also to long then "K. D. Harris" ... "K. Harris" or even "K. H."

    How can we recognize that the current text is getting truncated?