Add TextOverflow into TextStyle (#78927)
This commit is contained in:
parent
dba71259d5
commit
65388ee2ee
@ -21,6 +21,24 @@ export 'package:flutter/services.dart' show TextRange, TextSelection;
|
||||
// defaults set in the engine (eg, LibTxt's text_style.h, paragraph_style.h).
|
||||
const double _kDefaultFontSize = 14.0;
|
||||
|
||||
/// How overflowing text should be handled.
|
||||
///
|
||||
/// A [TextOverflow] can be passed to [Text] and [RichText] via their
|
||||
/// [Text.overflow] and [RichText.overflow] properties respectively.
|
||||
enum TextOverflow {
|
||||
/// Clip the overflowing text to fix its container.
|
||||
clip,
|
||||
|
||||
/// Fade the overflowing text to transparent.
|
||||
fade,
|
||||
|
||||
/// Use an ellipsis to indicate that the text has overflowed.
|
||||
ellipsis,
|
||||
|
||||
/// Render overflowing text outside of its container.
|
||||
visible,
|
||||
}
|
||||
|
||||
/// Holds the [Size] and baseline required to represent the dimensions of
|
||||
/// a placeholder in text.
|
||||
///
|
||||
|
@ -10,6 +10,7 @@ import 'package:flutter/foundation.dart';
|
||||
import 'basic_types.dart';
|
||||
import 'colors.dart';
|
||||
import 'strut_style.dart';
|
||||
import 'text_painter.dart';
|
||||
|
||||
const String _kDefaultDebugLabel = 'unknown';
|
||||
|
||||
@ -480,6 +481,7 @@ class TextStyle with Diagnosticable {
|
||||
String? fontFamily,
|
||||
List<String>? fontFamilyFallback,
|
||||
String? package,
|
||||
this.overflow,
|
||||
}) : fontFamily = package == null ? fontFamily : 'packages/$package/$fontFamily',
|
||||
_fontFamilyFallback = fontFamilyFallback,
|
||||
_package = package,
|
||||
@ -758,6 +760,9 @@ class TextStyle with Diagnosticable {
|
||||
/// these variants will be used for rendering.
|
||||
final List<ui.FontFeature>? fontFeatures;
|
||||
|
||||
/// How visual text overflow should be handled.
|
||||
final TextOverflow? overflow;
|
||||
|
||||
/// Creates a copy of this text style but with the given fields replaced with
|
||||
/// the new values.
|
||||
///
|
||||
@ -791,6 +796,7 @@ class TextStyle with Diagnosticable {
|
||||
TextDecorationStyle? decorationStyle,
|
||||
double? decorationThickness,
|
||||
String? debugLabel,
|
||||
TextOverflow? overflow,
|
||||
}) {
|
||||
assert(color == null || foreground == null, _kColorForegroundWarning);
|
||||
assert(backgroundColor == null || background == null, _kColorBackgroundWarning);
|
||||
@ -824,6 +830,7 @@ class TextStyle with Diagnosticable {
|
||||
decorationStyle: decorationStyle ?? this.decorationStyle,
|
||||
decorationThickness: decorationThickness ?? this.decorationThickness,
|
||||
debugLabel: newDebugLabel,
|
||||
overflow: overflow ?? this.overflow
|
||||
);
|
||||
}
|
||||
|
||||
@ -881,6 +888,7 @@ class TextStyle with Diagnosticable {
|
||||
Locale? locale,
|
||||
List<ui.Shadow>? shadows,
|
||||
List<ui.FontFeature>? fontFeatures,
|
||||
TextOverflow? overflow,
|
||||
}) {
|
||||
assert(fontSizeFactor != null);
|
||||
assert(fontSizeDelta != null);
|
||||
@ -929,6 +937,7 @@ class TextStyle with Diagnosticable {
|
||||
decorationColor: decorationColor ?? this.decorationColor,
|
||||
decorationStyle: decorationStyle ?? this.decorationStyle,
|
||||
decorationThickness: decorationThickness == null ? null : decorationThickness! * decorationThicknessFactor + decorationThicknessDelta,
|
||||
overflow: overflow ?? this.overflow,
|
||||
debugLabel: modifiedDebugLabel,
|
||||
);
|
||||
}
|
||||
@ -989,6 +998,7 @@ class TextStyle with Diagnosticable {
|
||||
decorationColor: other.decorationColor,
|
||||
decorationStyle: other.decorationStyle,
|
||||
decorationThickness: other.decorationThickness,
|
||||
overflow: other.overflow,
|
||||
debugLabel: mergedDebugLabel,
|
||||
);
|
||||
}
|
||||
@ -1043,6 +1053,7 @@ class TextStyle with Diagnosticable {
|
||||
decorationColor: Color.lerp(null, b.decorationColor, t),
|
||||
decorationStyle: t < 0.5 ? null : b.decorationStyle,
|
||||
decorationThickness: t < 0.5 ? null : b.decorationThickness,
|
||||
overflow: t < 0.5 ? null : b.overflow,
|
||||
debugLabel: lerpDebugLabel,
|
||||
);
|
||||
}
|
||||
@ -1071,6 +1082,7 @@ class TextStyle with Diagnosticable {
|
||||
decorationColor: Color.lerp(a.decorationColor, null, t),
|
||||
decorationStyle: t < 0.5 ? a.decorationStyle : null,
|
||||
decorationThickness: t < 0.5 ? a.decorationThickness : null,
|
||||
overflow: t < 0.5 ? a.overflow : null,
|
||||
debugLabel: lerpDebugLabel,
|
||||
);
|
||||
}
|
||||
@ -1106,6 +1118,7 @@ class TextStyle with Diagnosticable {
|
||||
decorationColor: Color.lerp(a.decorationColor, b.decorationColor, t),
|
||||
decorationStyle: t < 0.5 ? a.decorationStyle : b.decorationStyle,
|
||||
decorationThickness: ui.lerpDouble(a.decorationThickness ?? b.decorationThickness, b.decorationThickness ?? a.decorationThickness, t),
|
||||
overflow: t < 0.5 ? a.overflow : b.overflow,
|
||||
debugLabel: lerpDebugLabel,
|
||||
);
|
||||
}
|
||||
@ -1218,7 +1231,8 @@ class TextStyle with Diagnosticable {
|
||||
background != other.background ||
|
||||
!listEquals(shadows, other.shadows) ||
|
||||
!listEquals(fontFeatures, other.fontFeatures) ||
|
||||
!listEquals(fontFamilyFallback, other.fontFamilyFallback))
|
||||
!listEquals(fontFamilyFallback, other.fontFamilyFallback) ||
|
||||
overflow != other.overflow)
|
||||
return RenderComparison.layout;
|
||||
if (color != other.color ||
|
||||
backgroundColor != other.backgroundColor ||
|
||||
@ -1258,7 +1272,8 @@ class TextStyle with Diagnosticable {
|
||||
&& other.decorationThickness == decorationThickness
|
||||
&& listEquals(other.shadows, shadows)
|
||||
&& listEquals(other.fontFeatures, fontFeatures)
|
||||
&& listEquals(other.fontFamilyFallback, fontFamilyFallback);
|
||||
&& listEquals(other.fontFamilyFallback, fontFamilyFallback)
|
||||
&& other.overflow == overflow;
|
||||
}
|
||||
|
||||
@override
|
||||
@ -1285,6 +1300,7 @@ class TextStyle with Diagnosticable {
|
||||
hashList(shadows),
|
||||
hashList(fontFeatures),
|
||||
hashList(fontFamilyFallback),
|
||||
overflow,
|
||||
]);
|
||||
}
|
||||
|
||||
@ -1355,5 +1371,7 @@ class TextStyle with Diagnosticable {
|
||||
|
||||
if (!styleSpecified)
|
||||
properties.add(FlagProperty('inherit', value: inherit, ifTrue: '$prefix<all styles inherited>', ifFalse: '$prefix<no style specified>'));
|
||||
|
||||
styles.add(EnumProperty<TextOverflow>('${prefix}overflow', overflow, defaultValue: null));
|
||||
}
|
||||
}
|
||||
|
@ -16,24 +16,6 @@ import 'box.dart';
|
||||
import 'debug.dart';
|
||||
import 'object.dart';
|
||||
|
||||
/// How overflowing text should be handled.
|
||||
///
|
||||
/// A [TextOverflow] can be passed to [Text] and [RichText] via their
|
||||
/// [Text.overflow] and [RichText.overflow] properties respectively.
|
||||
enum TextOverflow {
|
||||
/// Clip the overflowing text to fix its container.
|
||||
clip,
|
||||
|
||||
/// Fade the overflowing text to transparent.
|
||||
fade,
|
||||
|
||||
/// Use an ellipsis to indicate that the text has overflowed.
|
||||
ellipsis,
|
||||
|
||||
/// Render overflowing text outside of its container.
|
||||
visible,
|
||||
}
|
||||
|
||||
const String _kEllipsis = '\u2026';
|
||||
|
||||
/// Parent data for use with [RenderParagraph].
|
||||
|
@ -467,7 +467,8 @@ class Text extends StatelessWidget {
|
||||
|
||||
/// How visual overflow should be handled.
|
||||
///
|
||||
/// Defaults to retrieving the value from the nearest [DefaultTextStyle] ancestor.
|
||||
/// If this is null [TextStyle.overflow] will be used, otherwise the value
|
||||
/// from the nearest [DefaultTextStyle] ancestor will be used.
|
||||
final TextOverflow? overflow;
|
||||
|
||||
/// The number of font pixels for each logical pixel.
|
||||
@ -526,7 +527,7 @@ class Text extends StatelessWidget {
|
||||
textDirection: textDirection, // RichText uses Directionality.of to obtain a default if this is null.
|
||||
locale: locale, // RichText uses Localizations.localeOf to obtain a default if this is null
|
||||
softWrap: softWrap ?? defaultTextStyle.softWrap,
|
||||
overflow: overflow ?? defaultTextStyle.overflow,
|
||||
overflow: overflow ?? effectiveTextStyle?.overflow ?? defaultTextStyle.overflow,
|
||||
textScaleFactor: textScaleFactor ?? MediaQuery.textScaleFactorOf(context),
|
||||
maxLines: maxLines ?? defaultTextStyle.maxLines,
|
||||
strutStyle: strutStyle,
|
||||
|
@ -744,6 +744,8 @@ class _TextStyleProxy implements TextStyle {
|
||||
List<Shadow>? get shadows => _delegate.shadows;
|
||||
@override
|
||||
List<ui.FontFeature>? get fontFeatures => _delegate.fontFeatures;
|
||||
@override
|
||||
TextOverflow? get overflow => _delegate.overflow;
|
||||
|
||||
@override
|
||||
String toString({ DiagnosticLevel minLevel = DiagnosticLevel.info }) =>
|
||||
@ -785,6 +787,7 @@ class _TextStyleProxy implements TextStyle {
|
||||
Locale? locale,
|
||||
List<ui.Shadow>? shadows,
|
||||
List<ui.FontFeature>? fontFeatures,
|
||||
TextOverflow? overflow,
|
||||
}) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
@ -819,6 +822,7 @@ class _TextStyleProxy implements TextStyle {
|
||||
TextDecorationStyle? decorationStyle,
|
||||
double? decorationThickness,
|
||||
String? debugLabel,
|
||||
TextOverflow? overflow,
|
||||
}) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
@ -1248,6 +1248,21 @@ void main() {
|
||||
// The inline spans are rendered in one vertical run, the widest one determines the min intrinsic width.
|
||||
expect(paragraph.getMinIntrinsicWidth(0.0), 200);
|
||||
});
|
||||
|
||||
testWidgets('Text uses TextStyle.overflow', (WidgetTester tester) async {
|
||||
const TextOverflow overflow = TextOverflow.fade;
|
||||
|
||||
await tester.pumpWidget( const Text(
|
||||
'Hello World',
|
||||
textDirection: TextDirection.ltr,
|
||||
style: TextStyle(overflow: overflow),
|
||||
));
|
||||
|
||||
final RichText richText = tester.firstWidget(find.byType(RichText));
|
||||
|
||||
expect(richText.overflow, overflow);
|
||||
expect(richText.text.style!.overflow, overflow);
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _pumpTextWidget({
|
||||
|
Loading…
x
Reference in New Issue
Block a user