Skip to content

Instantly share code, notes, and snippets.

@lukepighetti
Last active May 1, 2023 21:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lukepighetti/536d691f741bc32153ab6e3f0e0fa045 to your computer and use it in GitHub Desktop.
Save lukepighetti/536d691f741bc32153ab6e3f0e0fa045 to your computer and use it in GitHub Desktop.
import 'package:app/extensions.dart';
import 'package:flutter/material.dart';
class AutoFillText extends StatelessWidget {
const AutoFillText(
this.text, {
super.key,
this.textStyle,
this.minFontSize = 18,
});
final String text;
final double minFontSize;
final TextStyle? textStyle;
@override
Widget build(BuildContext context) {
var style = DefaultTextStyle.of(context).style;
if (textStyle != null) {
style = style.merge(textStyle);
}
return LayoutBuilder(
builder: (context, constraints) {
const step = 1.0;
final frameSize = constraints.bounded;
final maxFontSize = style.fontSize!;
var textSize = style.size(text, maxWidth: frameSize.width);
var fontSize = maxFontSize;
while (!frameSize.containsSize(textSize) &&
fontSize <= maxFontSize &&
fontSize >= minFontSize) {
textSize = style
.copyWith(fontSize: fontSize)
.size(text, maxWidth: frameSize.width);
fontSize -= step;
}
return Text(
text,
style: style.copyWith(fontSize: fontSize),
overflow: TextOverflow.fade,
);
},
);
}
}
extension BoxConstraintsExtensions on BoxConstraints {
bool get isBounded => hasBoundedHeight && hasBoundedWidth;
Size get bounded {
assert(isBounded);
return biggest;
}
}
extension SizeExtensions on Size {
bool containsSize(Size other) {
return width >= other.width && height >= other.height;
}
}
extension TextStyleExtensions on TextStyle {
Size size(String text, {double maxWidth = double.infinity}) {
final textSpan = TextSpan(text: text, style: this);
final textPainter = TextPainter(
text: textSpan,
textDirection: TextDirection.ltr,
maxLines: null,
textAlign: TextAlign.left,
);
textPainter.layout(maxWidth: maxWidth);
return textPainter.size;
}
}
@lukepighetti
Copy link
Author

Simple text that fills the container. Not sure why this hasn't been solved in four years. And if it has, why I couldn't find it.

foo.mp4

@mbaz2
Copy link

mbaz2 commented May 1, 2023

that's a great way of handling text! just wondering with your extensions, for bounded are you getting the max height and width of the container like this?

final frameSize = Size(constraints.maxWidth, constraints.maxHeight);

@lukepighetti
Copy link
Author

lukepighetti commented May 1, 2023

Thanks for the reminder, I updated the code to include bounded and other extensions

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment