Reputation: 4199
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
Upvotes: 11
Views: 13198
Reputation: 326
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();
}
Upvotes: 4
Reputation: 2529
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,
),
],
)
Upvotes: 6
Reputation: 5423
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(),
],
)
Upvotes: 4