Add Text.rich constructor to Text widget (#15317)
* add fromSpan constructor to Text widget and simple smoke test:
* change fromSpan to rich, clean up comments
* 'directly from' to 'with'
* make sure text styles are applied to either data or textspan. add diagnostic properties for span
* add expectation for text style to test case
* some work on diagnostics and docs
diff --git a/packages/flutter/lib/src/widgets/text.dart b/packages/flutter/lib/src/widgets/text.dart
index b163638..d933f0e 100644
--- a/packages/flutter/lib/src/widgets/text.dart
+++ b/packages/flutter/lib/src/widgets/text.dart
@@ -164,8 +164,9 @@
/// for example, to make the text bold while using the default font family and
/// size.
///
-/// To display text that uses multiple styles (e.g., a paragraph with some bold
-/// words), use [RichText].
+/// Using the [new TextSpan.rich] constructor, the [Text] widget can also be
+/// created with a [TextSpan] to display text that use multiple styles
+/// (e.g., a paragraph with some bold words).
///
/// ## Sample code
///
@@ -210,11 +211,33 @@
this.textScaleFactor,
this.maxLines,
}) : assert(data != null),
+ textSpan = null,
super(key: key);
+ /// Creates a text widget with a [TextSpan].
+ const Text.rich(this.textSpan, {
+ Key key,
+ this.style,
+ this.textAlign,
+ this.textDirection,
+ this.softWrap,
+ this.overflow,
+ this.textScaleFactor,
+ this.maxLines,
+ }): assert(textSpan != null),
+ data = null,
+ super(key: key);
+
/// The text to display.
+ ///
+ /// This will be null if a [textSpan] is provided instead.
final String data;
+ /// The text to display as a [TextSpan].
+ ///
+ /// This will be null if [data] is provided instead.
+ final TextSpan textSpan;
+
/// If non-null, the style to use for this text.
///
/// If the style's "inherit" property is true, the style will be merged with
@@ -287,7 +310,8 @@
text: new TextSpan(
style: effectiveTextStyle,
text: data,
- )
+ children: textSpan != null ? <TextSpan>[textSpan] : null,
+ ),
);
}
@@ -295,6 +319,9 @@
void debugFillProperties(DiagnosticPropertiesBuilder description) {
super.debugFillProperties(description);
description.add(new StringProperty('data', data, showName: false));
+ if (textSpan != null) {
+ description.add(textSpan.toDiagnosticsNode(name: 'textSpan', style: DiagnosticsTreeStyle.transition));
+ }
style?.debugFillProperties(description);
description.add(new EnumProperty<TextAlign>('textAlign', textAlign, defaultValue: null));
description.add(new EnumProperty<TextDirection>('textDirection', textDirection, defaultValue: null));
diff --git a/packages/flutter/test/widgets/text_test.dart b/packages/flutter/test/widgets/text_test.dart
index b1a2f9c..0d4c97f 100644
--- a/packages/flutter/test/widgets/text_test.dart
+++ b/packages/flutter/test/widgets/text_test.dart
@@ -85,4 +85,28 @@
expect(message, contains('Directionality'));
expect(message, contains(' Text '));
});
+
+ testWidgets('Text can be created from TextSpans and uses defaultTextStyle', (WidgetTester tester) async {
+ await tester.pumpWidget(
+ const DefaultTextStyle(
+ style: const TextStyle(
+ fontSize: 20.0,
+ ),
+ child: const Text.rich(
+ const TextSpan(
+ text: 'Hello',
+ children: const <TextSpan>[
+ const TextSpan(text: ' beautiful ', style: const TextStyle(fontStyle: FontStyle.italic)),
+ const TextSpan(text: 'world', style: const TextStyle(fontWeight: FontWeight.bold)),
+ ],
+ ),
+ textDirection: TextDirection.ltr,
+ ),
+ ),
+ );
+
+ final RichText text = tester.firstWidget(find.byType(RichText));
+ expect(text, isNotNull);
+ expect(text.text.style.fontSize, 20.0);
+ });
}