Unverified Commit 9d0041c9 authored by Ian Hickson's avatar Ian Hickson Committed by GitHub

AnimatedAlign (#12871)

parent 797b39e9
......@@ -1242,13 +1242,20 @@ class Align extends SingleChildRenderObjectWidget {
/// How to align the child.
///
/// The x and y values of the alignment control the horizontal and vertical
/// The x and y values of the [Alignment] control the horizontal and vertical
/// alignment, respectively. An x value of -1.0 means that the left edge of
/// the child is aligned with the left edge of the parent whereas an x value
/// of 1.0 means that the right edge of the child is aligned with the right
/// edge of the parent. Other values interpolate (and extrapolate) linearly.
/// For example, a value of 0.0 means that the center of the child is aligned
/// with the center of the parent.
///
/// See also:
///
/// * [Alignment], which has more details and some convenience constants for
/// common positions.
/// * [AlignmentDirectional], which has a horizontal coordinate orientation
/// that depends on the [TextDirection].
final AlignmentGeometry alignment;
/// If non-null, sets its width to the child's width multiplied by this factor.
......
......@@ -551,6 +551,80 @@ class _AnimatedPaddingState extends AnimatedWidgetBaseState<AnimatedPadding> {
}
}
/// Animated version of [Align] which automatically transitions the child's
/// position over a given duration whenever the given [alignment] changes.
///
/// See also:
///
/// * [AnimatedContainer], which can transition more values at once.
class AnimatedAlign extends ImplicitlyAnimatedWidget {
/// Creates a widget that positions its child by an alignment that animates
/// implicitly.
///
/// The [alignment], [curve], and [duration] arguments must not be null.
const AnimatedAlign({
Key key,
@required this.alignment,
this.child,
Curve curve: Curves.linear,
@required Duration duration,
}) : assert(alignment != null),
super(key: key, curve: curve, duration: duration);
/// How to align the child.
///
/// The x and y values of the [Alignment] control the horizontal and vertical
/// alignment, respectively. An x value of -1.0 means that the left edge of
/// the child is aligned with the left edge of the parent whereas an x value
/// of 1.0 means that the right edge of the child is aligned with the right
/// edge of the parent. Other values interpolate (and extrapolate) linearly.
/// For example, a value of 0.0 means that the center of the child is aligned
/// with the center of the parent.
///
/// See also:
///
/// * [Alignment], which has more details and some convenience constants for
/// common positions.
/// * [AlignmentDirectional], which has a horizontal coordinate orientation
/// that depends on the [TextDirection].
final AlignmentGeometry alignment;
/// The widget below this widget in the tree.
final Widget child;
@override
_AnimatedAlignState createState() => new _AnimatedAlignState();
@override
void debugFillProperties(DiagnosticPropertiesBuilder description) {
super.debugFillProperties(description);
description.add(new DiagnosticsProperty<AlignmentGeometry>('alignment', alignment));
}
}
class _AnimatedAlignState extends AnimatedWidgetBaseState<AnimatedAlign> {
AlignmentGeometryTween _alignment;
@override
void forEachTween(TweenVisitor<dynamic> visitor) {
_alignment = visitor(_alignment, widget.alignment, (dynamic value) => new AlignmentGeometryTween(begin: value));
}
@override
Widget build(BuildContext context) {
return new Align(
alignment: _alignment.evaluate(animation),
child: widget.child,
);
}
@override
void debugFillProperties(DiagnosticPropertiesBuilder description) {
super.debugFillProperties(description);
description.add(new DiagnosticsProperty<AlignmentGeometryTween>('alignment', _alignment, defaultValue: null));
}
}
/// Animated version of [Positioned] which automatically transitions the child's
/// position over a given duration whenever the given position changes.
///
......
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
void main() {
testWidgets('AnimatedAlign.debugFillProperties', (WidgetTester tester) async {
final AnimatedAlign box = const AnimatedAlign(
alignment: Alignment.topCenter,
curve: Curves.ease,
duration: const Duration(milliseconds: 200),
);
expect(box, hasOneLineDescription);
});
testWidgets('AnimatedAlign alignment visual-to-directional animation', (WidgetTester tester) async {
final Key target = new UniqueKey();
await tester.pumpWidget(
new Directionality(
textDirection: TextDirection.rtl,
child: new AnimatedAlign(
duration: const Duration(milliseconds: 200),
alignment: Alignment.topRight,
child: new SizedBox(key: target, width: 100.0, height: 200.0),
),
),
);
expect(tester.getSize(find.byKey(target)), const Size(100.0, 200.0));
expect(tester.getTopRight(find.byKey(target)), const Offset(800.0, 0.0));
await tester.pumpWidget(
new Directionality(
textDirection: TextDirection.rtl,
child: new AnimatedAlign(
duration: const Duration(milliseconds: 200),
alignment: AlignmentDirectional.bottomStart,
child: new SizedBox(key: target, width: 100.0, height: 200.0),
),
),
);
expect(tester.getSize(find.byKey(target)), const Size(100.0, 200.0));
expect(tester.getTopRight(find.byKey(target)), const Offset(800.0, 0.0));
await tester.pump(const Duration(milliseconds: 100));
expect(tester.getSize(find.byKey(target)), const Size(100.0, 200.0));
expect(tester.getTopRight(find.byKey(target)), const Offset(800.0, 200.0));
await tester.pump(const Duration(milliseconds: 500));
expect(tester.getSize(find.byKey(target)), const Size(100.0, 200.0));
expect(tester.getTopRight(find.byKey(target)), const Offset(800.0, 400.0));
});
}
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