Skip to content

Commit b4cf203

Browse files
authored
Add missing features to DefaultTextStyleTransition and AnimatedDefaultTextStyle (flutter#51517)
1 parent 3489da9 commit b4cf203

File tree

6 files changed

+145
-4
lines changed

6 files changed

+145
-4
lines changed

packages/flutter/lib/src/material/material.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ class _MaterialState extends State<Material> with TickerProviderStateMixin {
350350
);
351351
Widget contents = widget.child;
352352
if (contents != null) {
353-
contents = AnimatedDefaultTextStyle(
353+
contents = AnimatedDefaultTextStyle.merge(
354354
style: widget.textStyle ?? Theme.of(context).textTheme.bodyText2,
355355
duration: widget.animationDuration,
356356
child: contents,

packages/flutter/lib/src/widgets/implicit_animations.dart

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1582,14 +1582,67 @@ class AnimatedDefaultTextStyle extends ImplicitlyAnimatedWidget {
15821582
/// See [DefaultTextStyle.maxLines] for more details.
15831583
final int maxLines;
15841584

1585-
/// The strategy to use when calculating the width of the Text.
1586-
///
1587-
/// See [TextWidthBasis] for possible values and their implications.
1585+
/// {@macro lutter.widgets.text.DefaultTextStyle.tetWidthBasis}
15881586
final TextWidthBasis textWidthBasis;
15891587

15901588
/// {@macro flutter.dart:ui.textHeightBehavior}
15911589
final ui.TextHeightBehavior textHeightBehavior;
15921590

1591+
/// Creates an animated default text style that overrides the text styles in
1592+
/// scope at this point in the widget tree.
1593+
///
1594+
/// The given [style] is merged with the [style] from the default text style
1595+
/// for the [BuildContext] where the widget is inserted, and any of the other
1596+
/// arguments that are not null replace the corresponding properties on that
1597+
/// same default text style.
1598+
///
1599+
/// This constructor cannot be used to override the [maxLines] property of the
1600+
/// ancestor with the value null, since null here is used to mean "defer to
1601+
/// ancestor". To replace a non-null [maxLines] from an ancestor with the null
1602+
/// value (to remove the restriction on number of lines), manually obtain the
1603+
/// ambient [DefaultTextStyle] using [DefaultTextStyle.of], then create a new
1604+
/// [DefaultTextStyle] using the [new DefaultTextStyle] constructor directly.
1605+
/// See the source below for an example of how to do this (since that's
1606+
/// essentially what this constructor does).
1607+
///
1608+
/// Since the ancestor may not have been an AnimatedDefaultTextStyle, the
1609+
/// [duration] property is required.
1610+
static Widget merge({
1611+
Key key,
1612+
@required Widget child,
1613+
TextStyle style,
1614+
TextAlign textAlign,
1615+
bool softWrap,
1616+
TextOverflow overflow,
1617+
int maxLines,
1618+
TextWidthBasis textWidthBasis,
1619+
ui.TextHeightBehavior textHeightBehavior,
1620+
Curve curve = Curves.linear,
1621+
@required Duration duration,
1622+
VoidCallback onEnd,
1623+
}) {
1624+
assert(child != null);
1625+
return Builder(
1626+
builder: (BuildContext context) {
1627+
final DefaultTextStyle parent = DefaultTextStyle.of(context);
1628+
return AnimatedDefaultTextStyle(
1629+
key: key,
1630+
style: parent.style.merge(style),
1631+
textAlign: textAlign ?? parent.textAlign,
1632+
softWrap: softWrap ?? parent.softWrap,
1633+
overflow: overflow ?? parent.overflow,
1634+
maxLines: maxLines ?? parent.maxLines,
1635+
textWidthBasis: textWidthBasis ?? parent.textWidthBasis,
1636+
textHeightBehavior: textHeightBehavior ?? parent.textHeightBehavior,
1637+
duration: duration,
1638+
curve: curve,
1639+
onEnd: onEnd,
1640+
child: child,
1641+
);
1642+
},
1643+
);
1644+
}
1645+
15931646
@override
15941647
_AnimatedDefaultTextStyleState createState() => _AnimatedDefaultTextStyleState();
15951648

packages/flutter/lib/src/widgets/text.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ class DefaultTextStyle extends InheritedTheme {
9595
TextOverflow overflow,
9696
int maxLines,
9797
TextWidthBasis textWidthBasis,
98+
ui.TextHeightBehavior textHeightBehavior,
9899
@required Widget child,
99100
}) {
100101
assert(child != null);
@@ -109,6 +110,7 @@ class DefaultTextStyle extends InheritedTheme {
109110
overflow: overflow ?? parent.overflow,
110111
maxLines: maxLines ?? parent.maxLines,
111112
textWidthBasis: textWidthBasis ?? parent.textWidthBasis,
113+
textHeightBehavior: textHeightBehavior ?? parent.textHeightBehavior,
112114
child: child,
113115
);
114116
},
@@ -140,9 +142,11 @@ class DefaultTextStyle extends InheritedTheme {
140142
/// [Text.maxLines].
141143
final int maxLines;
142144

145+
/// {@template flutter.widgets.text.DefaultTextStyle.tetWidthBasis}
143146
/// The strategy to use when calculating the width of the Text.
144147
///
145148
/// See [TextWidthBasis] for possible values and their implications.
149+
/// {@endtemplate}
146150
final TextWidthBasis textWidthBasis;
147151

148152
/// {@macro flutter.dart:ui.textHeightBehavior}

packages/flutter/lib/src/widgets/transitions.dart

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// found in the LICENSE file.
44

55
import 'dart:math' as math;
6+
import 'dart:ui' as ui show TextHeightBehavior;
67

78
import 'package:flutter/rendering.dart';
89
import 'package:vector_math/vector_math_64.dart' show Matrix4;
@@ -969,8 +970,11 @@ class DefaultTextStyleTransition extends AnimatedWidget {
969970
this.softWrap = true,
970971
this.overflow = TextOverflow.clip,
971972
this.maxLines,
973+
this.textWidthBasis = TextWidthBasis.parent,
974+
this.textHeightBehavior,
972975
}) : assert(style != null),
973976
assert(child != null),
977+
assert(textWidthBasis != null),
974978
super(key: key, listenable: style);
975979

976980
/// The animation that controls the descendants' text style.
@@ -993,6 +997,14 @@ class DefaultTextStyleTransition extends AnimatedWidget {
993997
/// See [DefaultTextStyle.maxLines] for more details.
994998
final int maxLines;
995999

1000+
/// The strategy to use when calculating the width of the Text.
1001+
///
1002+
/// See [TextWidthBasis] for possible values and their implications.
1003+
final TextWidthBasis textWidthBasis;
1004+
1005+
/// {@macro flutter.dart:ui.textHeightBehavior}
1006+
final ui.TextHeightBehavior textHeightBehavior;
1007+
9961008
/// The widget below this widget in the tree.
9971009
///
9981010
/// {@macro flutter.widgets.child}
@@ -1006,6 +1018,8 @@ class DefaultTextStyleTransition extends AnimatedWidget {
10061018
softWrap: softWrap,
10071019
overflow: overflow,
10081020
maxLines: maxLines,
1021+
textWidthBasis: textWidthBasis,
1022+
textHeightBehavior: textHeightBehavior,
10091023
child: child,
10101024
);
10111025
}

packages/flutter/test/widgets/implicit_animations_test.dart

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,36 @@ void main() {
289289
expect(mockOnEndFunction.called, 1);
290290
});
291291

292+
testWidgets('AnimatedDefaultTextStyle merge test', (WidgetTester tester) async {
293+
const Key animatedKey = Key('animatedStyle');
294+
await tester.pumpWidget(
295+
Directionality(
296+
textDirection: TextDirection.rtl,
297+
child: DefaultTextStyle(
298+
style: const TextStyle(fontSize: 1234),
299+
textHeightBehavior: const TextHeightBehavior(
300+
applyHeightToFirstAscent: false,
301+
),
302+
maxLines: 10,
303+
softWrap: true,
304+
child: AnimatedDefaultTextStyle.merge(
305+
key: animatedKey,
306+
maxLines: 20,
307+
duration: const Duration(seconds: 10),
308+
child: const Text('woah!'),
309+
),
310+
),
311+
)
312+
);
313+
await tester.pump();
314+
315+
final Finder animatedDefaultTextStyleFinder = find.byKey(animatedKey);
316+
AnimatedDefaultTextStyle getAnimatedDefautTextStyleWidget(Finder finder) => tester.widget<AnimatedDefaultTextStyle>(finder);
317+
expect(getAnimatedDefautTextStyleWidget(animatedDefaultTextStyleFinder).textHeightBehavior, const TextHeightBehavior(applyHeightToFirstAscent: false,));
318+
expect(getAnimatedDefautTextStyleWidget(animatedDefaultTextStyleFinder).softWrap, true);
319+
expect(getAnimatedDefautTextStyleWidget(animatedDefaultTextStyleFinder).maxLines, 20);
320+
});
321+
292322
testWidgets('AnimatedPhysicalModel onEnd callback test', (WidgetTester tester) async {
293323
await tester.pumpWidget(wrap(
294324
child: TestAnimatedWidget(

packages/flutter/test/widgets/transitions_test.dart

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,4 +408,44 @@ void main() {
408408
expect(_getOpacity(tester, 'Fade In'), 1.0);
409409
});
410410
});
411+
412+
testWidgets('DefaultTextStyleTransition builds fully featured DefaultTextStyle', (WidgetTester tester) async {
413+
const DefaultTextStyleTransition styleTransition = DefaultTextStyleTransition(
414+
style: AlwaysStoppedAnimation<TextStyle>(TextStyle()),
415+
child: Text('step on legos!'),
416+
textAlign: TextAlign.right,
417+
softWrap: false,
418+
overflow: TextOverflow.fade,
419+
maxLines: 5,
420+
textWidthBasis: TextWidthBasis.longestLine,
421+
textHeightBehavior: TextHeightBehavior(
422+
applyHeightToFirstAscent: false,
423+
applyHeightToLastDescent: false,
424+
),
425+
);
426+
427+
expect((styleTransition.child as Text).data, 'step on legos!');
428+
expect(styleTransition.textAlign, TextAlign.right);
429+
expect(styleTransition.softWrap, false);
430+
expect(styleTransition.overflow, TextOverflow.fade);
431+
expect(styleTransition.maxLines, 5);
432+
expect(styleTransition.textWidthBasis, TextWidthBasis.longestLine);
433+
expect(styleTransition.textHeightBehavior, const TextHeightBehavior(
434+
applyHeightToFirstAscent: false,
435+
applyHeightToLastDescent: false,
436+
));
437+
438+
final DefaultTextStyle style = styleTransition.build(null) as DefaultTextStyle;
439+
440+
expect((style.child as Text).data, 'step on legos!');
441+
expect(style.textAlign, TextAlign.right);
442+
expect(style.softWrap, false);
443+
expect(style.overflow, TextOverflow.fade);
444+
expect(style.maxLines, 5);
445+
expect(style.textWidthBasis, TextWidthBasis.longestLine);
446+
expect(style.textHeightBehavior, const TextHeightBehavior(
447+
applyHeightToFirstAscent: false,
448+
applyHeightToLastDescent: false,
449+
));
450+
});
411451
}

0 commit comments

Comments
 (0)