Flutter: Text overflow ellipsis with three dots in the middle of the text

Viewed 6131

Is there any way to set the overflow dots to middle of the text in Flutter?

A normal use case is displaying filenames where the file extension is also visible to the user.

i.e., Currently, by using Text widget with overflow parameter as TextOverflow.ellipsis, we are getting the following

Text(
    "IMG_100232321321312312312312312321321312321343024.PNG",
    maxLines: 1,
    overflow: TextOverflow.ellipsis,
    style: Theme.of(context).textTheme.caption,
);

The result will be something like:

IMG_10023232132131...

Is there any way can we get a result like this:

IMG_10023...3024.PNG

3 Answers

Could do something like this..

Row(
      children: <Widget>[
        Spacer(),
        Expanded(
          child: Text(
            fileName.length > 8 ? fileName.substring(0, fileName.length - 8) : fileName,
            maxLines: 1,
            textAlign: TextAlign.end,
            overflow: TextOverflow.ellipsis,
          ),
        ),
        Expanded(
          child: Text(
            fileName.length > 8 ? fileName.substring(fileName.length - 8) : '',
            maxLines: 1,
            textAlign: TextAlign.start,
          ),
        ),
        Spacer(),
      ],
)

You can use path library like this:

import 'package:path/path.dart' as path;

   var data = "IMG_100232321321312312312312312321321312321343024.PNG";


          Row(
              children: <Widget>[
                Flexible(
                  child: Text(
                    data.split(path.extension(data))[0],
                    maxLines: 1,
                    overflow: TextOverflow.ellipsis,
                    style: Theme.of(context).textTheme.caption,
                  ),
                ),
                Text(
                  path.extension(data),
                  style: Theme.of(context).textTheme.caption,
                ),
              ],
            )

I was able to achieve that by this code.

class TextWithMidEllipsis extends StatelessWidget {
  final String data;
  final TextStyle style;
  final TextAlign? textAlign;
  const TextWithMidEllipsis(
    this.data, {
    Key? key,
    this.textAlign,
    this.style = const TextStyle(),
  }) : super(key: key);

  final textDirection = TextDirection.ltr;
  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (context, constraint) {
        if (constraint.maxWidth <= _textSize(data, style).width && data.length > 10) {
          var endPart = data.trim().substring(data.length - 10); 
          return Row(
            children: [
              Flexible(
                child: Text(
                  data.fixOverflowEllipsis,
                  style: style,
                  textAlign: textAlign,
                  overflow: TextOverflow.ellipsis,
                  textDirection: textDirection,
                ),
              ),
              Text(
                endPart,
                style: style,
                textDirection: textDirection,
                textAlign: textAlign,
              ),
            ],
          );
        }
        return Text(
          data,
          style: style,
          textAlign: textAlign,
          maxLines: 1,
          textDirection: textDirection,
        );
      },
    );
  }

  Size _textSize(String text, TextStyle style) {
    final TextPainter textPainter = TextPainter(
      text: TextSpan(
        text: text,
        style: style,
      ),
      maxLines: 1,
      textDirection: textDirection,
    )..layout(minWidth: 0, maxWidth: double.infinity);
    return textPainter.size;
  }
}
extension AppStringExtension on String {
  String get fixOverflowEllipsis =>
      Characters(this).replaceAll(Characters(''), Characters('\u{200B}')).toString();
}
Related