Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 1 addition & 11 deletions packages/flutter/lib/src/cupertino/date_picker.dart
Original file line number Diff line number Diff line change
Expand Up @@ -470,23 +470,13 @@ class CupertinoDatePicker extends StatefulWidget {

assert(longestText != '', 'column type is not appropriate');

final TextPainter painter = TextPainter(
return TextPainter.computeMaxIntrinsicWidth(
text: TextSpan(
style: _themeTextStyle(context),
text: longestText,
),
textDirection: Directionality.of(context),
);

// This operation is expensive and should be avoided. It is called here only
// because there's no other way to get the information we want without
// laying out the text.
painter.layout();
try {
return painter.maxIntrinsicWidth;
} finally {
painter.dispose();
}
}
}

Expand Down
80 changes: 80 additions & 0 deletions packages/flutter/lib/src/painting/text_painter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,86 @@ class TextPainter {
_textWidthBasis = textWidthBasis,
_textHeightBehavior = textHeightBehavior;

/// Computes the width of a configured [TextPainter].
///
/// This is a convenience method that creates a text painter with the supplied
/// parameters, lays it out with the supplied [minWidth] and [maxWidth], and
/// returns its [TextPainter.width] making sure to dispose the underlying
/// resources.
static double computeWidth({
required InlineSpan text,
TextAlign textAlign = TextAlign.start,
TextDirection? textDirection,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TextDirection must be non null I think?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was copied from the TextPainter ctor. I'd like to keep the types the same for ease of migration.

If we want to update this we should update the ctor as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh but I see what you're saying, on the regular object we can set this to some value later, whereas we can't with this method. Ok. In that case, I'll file a follow upt o make it non-nullable.

double textScaleFactor = 1.0,
int? maxLines,
String? ellipsis,
Locale? locale,
StrutStyle? strutStyle,
TextWidthBasis textWidthBasis = TextWidthBasis.parent,
ui.TextHeightBehavior? textHeightBehavior,
double minWidth = 0.0,
double maxWidth = double.infinity,
}) {
final TextPainter painter = TextPainter(
text: text,
textAlign: textAlign,
textDirection: textDirection,
textScaleFactor: textScaleFactor,
maxLines: maxLines,
ellipsis: ellipsis,
locale: locale,
strutStyle: strutStyle,
textWidthBasis: textWidthBasis,
textHeightBehavior: textHeightBehavior,
)..layout(minWidth: minWidth, maxWidth: maxWidth);

try {
return painter.width;
} finally {
painter.dispose();
}
}

/// Computes the max intrinsic width of a configured [TextPainter].
///
/// This is a convenience method that creates a text painter with the supplied
/// parameters, lays it out with the supplied [minWidth] and [maxWidth], and
/// returns its [TextPainter.maxIntrinsicWidth] making sure to dispose the
/// underlying resources.
static double computeMaxIntrinsicWidth({
required InlineSpan text,
TextAlign textAlign = TextAlign.start,
TextDirection? textDirection,
double textScaleFactor = 1.0,
int? maxLines,
String? ellipsis,
Locale? locale,
StrutStyle? strutStyle,
TextWidthBasis textWidthBasis = TextWidthBasis.parent,
ui.TextHeightBehavior? textHeightBehavior,
double minWidth = 0.0,
double maxWidth = double.infinity,
}) {
final TextPainter painter = TextPainter(
text: text,
textAlign: textAlign,
textDirection: textDirection,
textScaleFactor: textScaleFactor,
maxLines: maxLines,
ellipsis: ellipsis,
locale: locale,
strutStyle: strutStyle,
textWidthBasis: textWidthBasis,
textHeightBehavior: textHeightBehavior,
)..layout(minWidth: minWidth, maxWidth: maxWidth);

try {
return painter.maxIntrinsicWidth;
} finally {
painter.dispose();
}
}

// _paragraph being null means the text needs layout because of style changes.
// Setting _paragraph to null invalidates all the layout cache.
//
Expand Down
24 changes: 24 additions & 0 deletions packages/flutter/test/painting/text_painter_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1184,6 +1184,30 @@ void main() {
painter.dispose();
expect(painter.debugDisposed, true);
});

test('TextPainter computeWidth', () {
const InlineSpan text = TextSpan(text: 'foobar');
final TextPainter painter = TextPainter(text: text, textDirection: TextDirection.ltr);
painter.layout();
expect(painter.width, TextPainter.computeWidth(text: text, textDirection: TextDirection.ltr));

painter.layout(minWidth: 500);
expect(painter.width, TextPainter.computeWidth(text: text, textDirection: TextDirection.ltr, minWidth: 500));

painter.dispose();
});

test('TextPainter computeMaxIntrinsicWidth', () {
const InlineSpan text = TextSpan(text: 'foobar');
final TextPainter painter = TextPainter(text: text, textDirection: TextDirection.ltr);
painter.layout();
expect(painter.maxIntrinsicWidth, TextPainter.computeMaxIntrinsicWidth(text: text, textDirection: TextDirection.ltr));

painter.layout(minWidth: 500);
expect(painter.maxIntrinsicWidth, TextPainter.computeMaxIntrinsicWidth(text: text, textDirection: TextDirection.ltr, minWidth: 500));

painter.dispose();
});
}

class MockCanvas extends Fake implements Canvas {
Expand Down