diff --git a/packages/flutter/lib/src/widgets/text.dart b/packages/flutter/lib/src/widgets/text.dart index b163638951..d933f0eccc 100644 --- a/packages/flutter/lib/src/widgets/text.dart +++ b/packages/flutter/lib/src/widgets/text.dart @@ -164,8 +164,9 @@ class DefaultTextStyle extends InheritedWidget { /// 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 @@ class Text extends StatelessWidget { 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 @@ class Text extends StatelessWidget { text: new TextSpan( style: effectiveTextStyle, text: data, - ) + children: textSpan != null ? [textSpan] : null, + ), ); } @@ -295,6 +319,9 @@ class Text extends StatelessWidget { 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, defaultValue: null)); description.add(new EnumProperty('textDirection', textDirection, defaultValue: null)); diff --git a/packages/flutter/test/widgets/text_test.dart b/packages/flutter/test/widgets/text_test.dart index b1a2f9c15b..0d4c97fe22 100644 --- a/packages/flutter/test/widgets/text_test.dart +++ b/packages/flutter/test/widgets/text_test.dart @@ -85,4 +85,28 @@ void main() { 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 [ + 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); + }); }