Unverified Commit b4cf2038 authored by Gary Qian's avatar Gary Qian Committed by GitHub

Add missing features to `DefaultTextStyleTransition` and `AnimatedDefaultTextStyle` (#51517)

parent 3489da93
......@@ -350,7 +350,7 @@ class _MaterialState extends State<Material> with TickerProviderStateMixin {
);
Widget contents = widget.child;
if (contents != null) {
contents = AnimatedDefaultTextStyle(
contents = AnimatedDefaultTextStyle.merge(
style: widget.textStyle ?? Theme.of(context).textTheme.bodyText2,
duration: widget.animationDuration,
child: contents,
......
......@@ -1582,14 +1582,67 @@ class AnimatedDefaultTextStyle extends ImplicitlyAnimatedWidget {
/// See [DefaultTextStyle.maxLines] for more details.
final int maxLines;
/// The strategy to use when calculating the width of the Text.
///
/// See [TextWidthBasis] for possible values and their implications.
/// {@macro lutter.widgets.text.DefaultTextStyle.tetWidthBasis}
final TextWidthBasis textWidthBasis;
/// {@macro flutter.dart:ui.textHeightBehavior}
final ui.TextHeightBehavior textHeightBehavior;
/// Creates an animated default text style that overrides the text styles in
/// scope at this point in the widget tree.
///
/// The given [style] is merged with the [style] from the default text style
/// for the [BuildContext] where the widget is inserted, and any of the other
/// arguments that are not null replace the corresponding properties on that
/// same default text style.
///
/// This constructor cannot be used to override the [maxLines] property of the
/// ancestor with the value null, since null here is used to mean "defer to
/// ancestor". To replace a non-null [maxLines] from an ancestor with the null
/// value (to remove the restriction on number of lines), manually obtain the
/// ambient [DefaultTextStyle] using [DefaultTextStyle.of], then create a new
/// [DefaultTextStyle] using the [new DefaultTextStyle] constructor directly.
/// See the source below for an example of how to do this (since that's
/// essentially what this constructor does).
///
/// Since the ancestor may not have been an AnimatedDefaultTextStyle, the
/// [duration] property is required.
static Widget merge({
Key key,
@required Widget child,
TextStyle style,
TextAlign textAlign,
bool softWrap,
TextOverflow overflow,
int maxLines,
TextWidthBasis textWidthBasis,
ui.TextHeightBehavior textHeightBehavior,
Curve curve = Curves.linear,
@required Duration duration,
VoidCallback onEnd,
}) {
assert(child != null);
return Builder(
builder: (BuildContext context) {
final DefaultTextStyle parent = DefaultTextStyle.of(context);
return AnimatedDefaultTextStyle(
key: key,
style: parent.style.merge(style),
textAlign: textAlign ?? parent.textAlign,
softWrap: softWrap ?? parent.softWrap,
overflow: overflow ?? parent.overflow,
maxLines: maxLines ?? parent.maxLines,
textWidthBasis: textWidthBasis ?? parent.textWidthBasis,
textHeightBehavior: textHeightBehavior ?? parent.textHeightBehavior,
duration: duration,
curve: curve,
onEnd: onEnd,
child: child,
);
},
);
}
@override
_AnimatedDefaultTextStyleState createState() => _AnimatedDefaultTextStyleState();
......
......@@ -95,6 +95,7 @@ class DefaultTextStyle extends InheritedTheme {
TextOverflow overflow,
int maxLines,
TextWidthBasis textWidthBasis,
ui.TextHeightBehavior textHeightBehavior,
@required Widget child,
}) {
assert(child != null);
......@@ -109,6 +110,7 @@ class DefaultTextStyle extends InheritedTheme {
overflow: overflow ?? parent.overflow,
maxLines: maxLines ?? parent.maxLines,
textWidthBasis: textWidthBasis ?? parent.textWidthBasis,
textHeightBehavior: textHeightBehavior ?? parent.textHeightBehavior,
child: child,
);
},
......@@ -140,9 +142,11 @@ class DefaultTextStyle extends InheritedTheme {
/// [Text.maxLines].
final int maxLines;
/// {@template flutter.widgets.text.DefaultTextStyle.tetWidthBasis}
/// The strategy to use when calculating the width of the Text.
///
/// See [TextWidthBasis] for possible values and their implications.
/// {@endtemplate}
final TextWidthBasis textWidthBasis;
/// {@macro flutter.dart:ui.textHeightBehavior}
......
......@@ -3,6 +3,7 @@
// found in the LICENSE file.
import 'dart:math' as math;
import 'dart:ui' as ui show TextHeightBehavior;
import 'package:flutter/rendering.dart';
import 'package:vector_math/vector_math_64.dart' show Matrix4;
......@@ -969,8 +970,11 @@ class DefaultTextStyleTransition extends AnimatedWidget {
this.softWrap = true,
this.overflow = TextOverflow.clip,
this.maxLines,
this.textWidthBasis = TextWidthBasis.parent,
this.textHeightBehavior,
}) : assert(style != null),
assert(child != null),
assert(textWidthBasis != null),
super(key: key, listenable: style);
/// The animation that controls the descendants' text style.
......@@ -993,6 +997,14 @@ class DefaultTextStyleTransition extends AnimatedWidget {
/// See [DefaultTextStyle.maxLines] for more details.
final int maxLines;
/// The strategy to use when calculating the width of the Text.
///
/// See [TextWidthBasis] for possible values and their implications.
final TextWidthBasis textWidthBasis;
/// {@macro flutter.dart:ui.textHeightBehavior}
final ui.TextHeightBehavior textHeightBehavior;
/// The widget below this widget in the tree.
///
/// {@macro flutter.widgets.child}
......@@ -1006,6 +1018,8 @@ class DefaultTextStyleTransition extends AnimatedWidget {
softWrap: softWrap,
overflow: overflow,
maxLines: maxLines,
textWidthBasis: textWidthBasis,
textHeightBehavior: textHeightBehavior,
child: child,
);
}
......
......@@ -289,6 +289,36 @@ void main() {
expect(mockOnEndFunction.called, 1);
});
testWidgets('AnimatedDefaultTextStyle merge test', (WidgetTester tester) async {
const Key animatedKey = Key('animatedStyle');
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.rtl,
child: DefaultTextStyle(
style: const TextStyle(fontSize: 1234),
textHeightBehavior: const TextHeightBehavior(
applyHeightToFirstAscent: false,
),
maxLines: 10,
softWrap: true,
child: AnimatedDefaultTextStyle.merge(
key: animatedKey,
maxLines: 20,
duration: const Duration(seconds: 10),
child: const Text('woah!'),
),
),
)
);
await tester.pump();
final Finder animatedDefaultTextStyleFinder = find.byKey(animatedKey);
AnimatedDefaultTextStyle getAnimatedDefautTextStyleWidget(Finder finder) => tester.widget<AnimatedDefaultTextStyle>(finder);
expect(getAnimatedDefautTextStyleWidget(animatedDefaultTextStyleFinder).textHeightBehavior, const TextHeightBehavior(applyHeightToFirstAscent: false,));
expect(getAnimatedDefautTextStyleWidget(animatedDefaultTextStyleFinder).softWrap, true);
expect(getAnimatedDefautTextStyleWidget(animatedDefaultTextStyleFinder).maxLines, 20);
});
testWidgets('AnimatedPhysicalModel onEnd callback test', (WidgetTester tester) async {
await tester.pumpWidget(wrap(
child: TestAnimatedWidget(
......
......@@ -408,4 +408,44 @@ void main() {
expect(_getOpacity(tester, 'Fade In'), 1.0);
});
});
testWidgets('DefaultTextStyleTransition builds fully featured DefaultTextStyle', (WidgetTester tester) async {
const DefaultTextStyleTransition styleTransition = DefaultTextStyleTransition(
style: AlwaysStoppedAnimation<TextStyle>(TextStyle()),
child: Text('step on legos!'),
textAlign: TextAlign.right,
softWrap: false,
overflow: TextOverflow.fade,
maxLines: 5,
textWidthBasis: TextWidthBasis.longestLine,
textHeightBehavior: TextHeightBehavior(
applyHeightToFirstAscent: false,
applyHeightToLastDescent: false,
),
);
expect((styleTransition.child as Text).data, 'step on legos!');
expect(styleTransition.textAlign, TextAlign.right);
expect(styleTransition.softWrap, false);
expect(styleTransition.overflow, TextOverflow.fade);
expect(styleTransition.maxLines, 5);
expect(styleTransition.textWidthBasis, TextWidthBasis.longestLine);
expect(styleTransition.textHeightBehavior, const TextHeightBehavior(
applyHeightToFirstAscent: false,
applyHeightToLastDescent: false,
));
final DefaultTextStyle style = styleTransition.build(null) as DefaultTextStyle;
expect((style.child as Text).data, 'step on legos!');
expect(style.textAlign, TextAlign.right);
expect(style.softWrap, false);
expect(style.overflow, TextOverflow.fade);
expect(style.maxLines, 5);
expect(style.textWidthBasis, TextWidthBasis.longestLine);
expect(style.textHeightBehavior, const TextHeightBehavior(
applyHeightToFirstAscent: false,
applyHeightToLastDescent: false,
));
});
}
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