Unverified Commit 2eb26f13 authored by Ian Hickson's avatar Ian Hickson Committed by GitHub

Update AnimatedDefaultTextStyle to match DefaultTextStyle (#13531)

We've added a bunch of non-animatable properties to DefaultTextStyle.
This adds them to AnimatedDefaultTextStyle so that you can use them
even when your text style is animating.
parent ee65db11
......@@ -945,18 +945,29 @@ class _AnimatedOpacityState extends AnimatedWidgetBaseState<AnimatedOpacity> {
/// default text style (the text style to apply to descendant [Text] widgets
/// without explicit style) over a given duration whenever the given style
/// changes.
///
/// The [textAlign], [softWrap], [textOverflow], and [maxLines] properties are
/// not animated and take effect immediately when changed.
class AnimatedDefaultTextStyle extends ImplicitlyAnimatedWidget {
/// Creates a widget that animates the default text style implicitly.
///
/// The [child], [style], [curve], and [duration] arguments must not be null.
/// The [child], [style], [softWrap], [overflow], [curve], and [duration]
/// arguments must not be null.
const AnimatedDefaultTextStyle({
Key key,
@required this.child,
@required this.style,
this.textAlign,
this.softWrap: true,
this.overflow: TextOverflow.clip,
this.maxLines,
Curve curve: Curves.linear,
@required Duration duration,
}) : assert(style != null),
assert(child != null),
assert(softWrap != null),
assert(overflow != null),
assert(maxLines == null || maxLines > 0),
super(key: key, curve: curve, duration: duration);
/// The widget below this widget in the tree.
......@@ -965,8 +976,34 @@ class AnimatedDefaultTextStyle extends ImplicitlyAnimatedWidget {
/// The target text style.
///
/// The text style must not be null.
///
/// When this property is changed, the style will be animated over [duration] time.
final TextStyle style;
/// How the text should be aligned horizontally.
///
/// This property takes effect immediately when changed, it is not animated.
final TextAlign textAlign;
/// Whether the text should break at soft line breaks.
///
/// This property takes effect immediately when changed, it is not animated.
///
/// See [DefaultTextStyle.softWrap] for more details.
final bool softWrap;
/// How visual overflow should be handled.
///
/// This property takes effect immediately when changed, it is not animated.
final TextOverflow overflow;
/// An optional maximum number of lines for the text to span, wrapping if necessary.
///
/// This property takes effect immediately when changed, it is not animated.
///
/// See [DefaultTextStyle.maxLines] for more details.
final int maxLines;
@override
_AnimatedDefaultTextStyleState createState() => new _AnimatedDefaultTextStyleState();
......@@ -974,6 +1011,10 @@ class AnimatedDefaultTextStyle extends ImplicitlyAnimatedWidget {
void debugFillProperties(DiagnosticPropertiesBuilder description) {
super.debugFillProperties(description);
style?.debugFillProperties(description);
description.add(new EnumProperty<TextAlign>('textAlign', textAlign, defaultValue: null));
description.add(new FlagProperty('softWrap', value: softWrap, ifTrue: 'wrapping at box width', ifFalse: 'no wrapping except at line break characters', showName: true));
description.add(new EnumProperty<TextOverflow>('overflow', overflow, defaultValue: null));
description.add(new IntProperty('maxLines', maxLines, defaultValue: null));
}
}
......@@ -989,7 +1030,11 @@ class _AnimatedDefaultTextStyleState extends AnimatedWidgetBaseState<AnimatedDef
Widget build(BuildContext context) {
return new DefaultTextStyle(
style: _style.evaluate(animation),
child: widget.child
textAlign: widget.textAlign,
softWrap: widget.softWrap,
overflow: widget.overflow,
maxLines: widget.maxLines,
child: widget.child,
);
}
}
......
......@@ -29,7 +29,7 @@ void main() {
softWrap: false,
overflow: TextOverflow.fade,
maxLines: 3,
child: textWidget
child: textWidget,
));
text = tester.firstWidget(find.byType(RichText));
......@@ -40,4 +40,60 @@ void main() {
expect(text.overflow, TextOverflow.fade);
expect(text.maxLines, 3);
});
testWidgets('AnimatedDefaultTextStyle changes propagate to Text', (WidgetTester tester) async {
const Text textWidget = const Text('Hello', textDirection: TextDirection.ltr);
const TextStyle s1 = const TextStyle(
fontSize: 10.0,
fontWeight: FontWeight.w800,
height: 123.0,
);
const TextStyle s2 = const TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.w200,
height: 1.0,
);
await tester.pumpWidget(const AnimatedDefaultTextStyle(
style: s1,
child: textWidget,
duration: const Duration(milliseconds: 1000),
));
final RichText text1 = tester.firstWidget(find.byType(RichText));
expect(text1, isNotNull);
expect(text1.text.style, s1);
expect(text1.textAlign, TextAlign.start);
expect(text1.softWrap, isTrue);
expect(text1.overflow, TextOverflow.clip);
expect(text1.maxLines, isNull);
await tester.pumpWidget(const AnimatedDefaultTextStyle(
style: s2,
textAlign: TextAlign.justify,
softWrap: false,
overflow: TextOverflow.fade,
maxLines: 3,
child: textWidget,
duration: const Duration(milliseconds: 1000),
));
final RichText text2 = tester.firstWidget(find.byType(RichText));
expect(text2, isNotNull);
expect(text2.text.style, s1); // animation hasn't started yet
expect(text2.textAlign, TextAlign.justify);
expect(text2.softWrap, false);
expect(text2.overflow, TextOverflow.fade);
expect(text2.maxLines, 3);
await tester.pump(const Duration(milliseconds: 1000));
final RichText text3 = tester.firstWidget(find.byType(RichText));
expect(text3, isNotNull);
expect(text3.text.style, s2); // animation has now finished
expect(text3.textAlign, TextAlign.justify);
expect(text3.softWrap, false);
expect(text3.overflow, TextOverflow.fade);
expect(text3.maxLines, 3);
});
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment