Commit 9fc9f402 authored by Adam Barth's avatar Adam Barth Committed by GitHub

Add RTL support for AnimatedCrossFade and AnimatedSize (#11920)

Fixes #11848
parent 9be9a409
......@@ -72,13 +72,14 @@ class RenderAnimatedSize extends RenderAligningShiftedBox {
@required TickerProvider vsync,
@required Duration duration,
Curve curve: Curves.linear,
FractionalOffset alignment: FractionalOffset.center,
FractionalOffsetGeometry alignment: FractionalOffset.center,
TextDirection textDirection,
RenderBox child,
}) : assert(vsync != null),
assert(duration != null),
assert(curve != null),
_vsync = vsync,
super(child: child, alignment: alignment) {
super(child: child, alignment: alignment, textDirection: textDirection) {
_controller = new AnimationController(
vsync: vsync,
duration: duration,
......
......@@ -166,7 +166,7 @@ class AnimatedCrossFade extends StatefulWidget {
/// How the children should be aligned while the size is animating.
///
/// Defaults to [FractionalOffset.topCenter].
final FractionalOffset alignment;
final FractionalOffsetGeometry alignment;
/// A builder that positions the [firstChild] and [secondChild] widgets.
///
......@@ -218,7 +218,7 @@ class AnimatedCrossFade extends StatefulWidget {
void debugFillProperties(DiagnosticPropertiesBuilder description) {
super.debugFillProperties(description);
description.add(new EnumProperty<CrossFadeState>('crossFadeState', crossFadeState));
description.add(new DiagnosticsProperty<FractionalOffset>('alignment', alignment, defaultValue: FractionalOffset.topCenter));
description.add(new DiagnosticsProperty<FractionalOffsetGeometry>('alignment', alignment, defaultValue: FractionalOffset.topCenter));
}
}
......@@ -356,6 +356,6 @@ class _AnimatedCrossFadeState extends State<AnimatedCrossFade> with TickerProvid
super.debugFillProperties(description);
description.add(new EnumProperty<CrossFadeState>('crossFadeState', widget.crossFadeState));
description.add(new DiagnosticsProperty<AnimationController>('controller', _controller, showName: false));
description.add(new DiagnosticsProperty<FractionalOffset>('alignment', widget.alignment, defaultValue: FractionalOffset.topCenter));
description.add(new DiagnosticsProperty<FractionalOffsetGeometry>('alignment', widget.alignment, defaultValue: FractionalOffset.topCenter));
}
}
......@@ -34,7 +34,7 @@ class AnimatedSize extends SingleChildRenderObjectWidget {
/// edge of the parent. Other values interpolate (and extrapolate) linearly.
/// For example, a value of 0.5 means that the center of the child is aligned
/// with the center of the parent.
final FractionalOffset alignment;
final FractionalOffsetGeometry alignment;
/// The animation curve when transitioning this widget's size to match the
/// child's size.
......@@ -54,16 +54,17 @@ class AnimatedSize extends SingleChildRenderObjectWidget {
duration: duration,
curve: curve,
vsync: vsync,
textDirection: Directionality.of(context),
);
}
@override
void updateRenderObject(BuildContext context,
RenderAnimatedSize renderObject) {
void updateRenderObject(BuildContext context, RenderAnimatedSize renderObject) {
renderObject
..alignment = alignment
..duration = duration
..curve = curve
..vsync = vsync;
..vsync = vsync
..textDirection = Directionality.of(context);
}
}
......@@ -14,16 +14,16 @@ void main() {
child: const AnimatedCrossFade(
firstChild: const SizedBox(
width: 100.0,
height: 100.0
height: 100.0,
),
secondChild: const SizedBox(
width: 200.0,
height: 200.0
height: 200.0,
),
duration: const Duration(milliseconds: 200),
crossFadeState: CrossFadeState.showFirst,
)
)
),
),
);
expect(find.byType(FadeTransition), findsNWidgets(2));
......@@ -36,16 +36,16 @@ void main() {
child: const AnimatedCrossFade(
firstChild: const SizedBox(
width: 100.0,
height: 100.0
height: 100.0,
),
secondChild: const SizedBox(
width: 200.0,
height: 200.0
height: 200.0,
),
duration: const Duration(milliseconds: 200),
crossFadeState: CrossFadeState.showSecond,
)
)
),
),
);
await tester.pump(const Duration(milliseconds: 100));
......@@ -62,16 +62,16 @@ void main() {
child: const AnimatedCrossFade(
firstChild: const SizedBox(
width: 100.0,
height: 100.0
height: 100.0,
),
secondChild: const SizedBox(
width: 200.0,
height: 200.0
height: 200.0,
),
duration: const Duration(milliseconds: 200),
crossFadeState: CrossFadeState.showSecond,
)
)
),
),
);
expect(find.byType(FadeTransition), findsNWidgets(2));
......@@ -80,7 +80,7 @@ void main() {
expect(box.size.height, equals(200.0));
});
testWidgets('AnimatedCrossFade alignment', (WidgetTester tester) async {
testWidgets('AnimatedCrossFade alignment (VISUAL)', (WidgetTester tester) async {
final Key firstKey = new UniqueKey();
final Key secondKey = new UniqueKey();
......@@ -91,17 +91,17 @@ void main() {
firstChild: new SizedBox(
key: firstKey,
width: 100.0,
height: 100.0
height: 100.0,
),
secondChild: new SizedBox(
key: secondKey,
width: 200.0,
height: 200.0
height: 200.0,
),
duration: const Duration(milliseconds: 200),
crossFadeState: CrossFadeState.showFirst
)
)
crossFadeState: CrossFadeState.showFirst,
),
),
);
await tester.pumpWidget(
......@@ -111,17 +111,75 @@ void main() {
firstChild: new SizedBox(
key: firstKey,
width: 100.0,
height: 100.0
height: 100.0,
),
secondChild: new SizedBox(
key: secondKey,
width: 200.0,
height: 200.0
height: 200.0,
),
duration: const Duration(milliseconds: 200),
crossFadeState: CrossFadeState.showSecond
)
)
crossFadeState: CrossFadeState.showSecond,
),
),
);
await tester.pump(const Duration(milliseconds: 100));
final RenderBox box1 = tester.renderObject(find.byKey(firstKey));
final RenderBox box2 = tester.renderObject(find.byKey(secondKey));
expect(box1.localToGlobal(Offset.zero), const Offset(275.0, 175.0));
expect(box2.localToGlobal(Offset.zero), const Offset(275.0, 175.0));
});
testWidgets('AnimatedCrossFade alignment (LTR)', (WidgetTester tester) async {
final Key firstKey = new UniqueKey();
final Key secondKey = new UniqueKey();
await tester.pumpWidget(
new Directionality(
textDirection: TextDirection.ltr,
child: new Center(
child: new AnimatedCrossFade(
alignment: FractionalOffsetDirectional.bottomEnd,
firstChild: new SizedBox(
key: firstKey,
width: 100.0,
height: 100.0,
),
secondChild: new SizedBox(
key: secondKey,
width: 200.0,
height: 200.0,
),
duration: const Duration(milliseconds: 200),
crossFadeState: CrossFadeState.showFirst,
),
),
),
);
await tester.pumpWidget(
new Directionality(
textDirection: TextDirection.ltr,
child: new Center(
child: new AnimatedCrossFade(
alignment: FractionalOffsetDirectional.bottomEnd,
firstChild: new SizedBox(
key: firstKey,
width: 100.0,
height: 100.0,
),
secondChild: new SizedBox(
key: secondKey,
width: 200.0,
height: 200.0,
),
duration: const Duration(milliseconds: 200),
crossFadeState: CrossFadeState.showSecond,
),
),
),
);
await tester.pump(const Duration(milliseconds: 100));
......@@ -132,6 +190,64 @@ void main() {
expect(box2.localToGlobal(Offset.zero), const Offset(275.0, 175.0));
});
testWidgets('AnimatedCrossFade alignment (RTL)', (WidgetTester tester) async {
final Key firstKey = new UniqueKey();
final Key secondKey = new UniqueKey();
await tester.pumpWidget(
new Directionality(
textDirection: TextDirection.rtl,
child: new Center(
child: new AnimatedCrossFade(
alignment: FractionalOffsetDirectional.bottomEnd,
firstChild: new SizedBox(
key: firstKey,
width: 100.0,
height: 100.0,
),
secondChild: new SizedBox(
key: secondKey,
width: 200.0,
height: 200.0,
),
duration: const Duration(milliseconds: 200),
crossFadeState: CrossFadeState.showFirst,
),
),
),
);
await tester.pumpWidget(
new Directionality(
textDirection: TextDirection.rtl,
child: new Center(
child: new AnimatedCrossFade(
alignment: FractionalOffsetDirectional.bottomEnd,
firstChild: new SizedBox(
key: firstKey,
width: 100.0,
height: 100.0,
),
secondChild: new SizedBox(
key: secondKey,
width: 200.0,
height: 200.0,
),
duration: const Duration(milliseconds: 200),
crossFadeState: CrossFadeState.showSecond,
),
),
),
);
await tester.pump(const Duration(milliseconds: 100));
final RenderBox box1 = tester.renderObject(find.byKey(firstKey));
final RenderBox box2 = tester.renderObject(find.byKey(secondKey));
expect(box1.localToGlobal(Offset.zero), const Offset(325.0, 175.0));
expect(box2.localToGlobal(Offset.zero), const Offset(325.0, 175.0));
});
Widget crossFadeWithWatcher({bool towardsSecond: false}) {
return new AnimatedCrossFade(
firstChild: const _TickerWatchingWidget(),
......
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