diff --git a/packages/flutter/lib/src/material/page.dart b/packages/flutter/lib/src/material/page.dart index 74db7d52e7..afc161fafa 100644 --- a/packages/flutter/lib/src/material/page.dart +++ b/packages/flutter/lib/src/material/page.dart @@ -12,31 +12,38 @@ const double _kMinFlingVelocity = 1.0; // screen width per second // Used for Android and Fuchsia. class _MountainViewPageTransition extends AnimatedWidget { - static final FractionalOffsetTween _kTween = new FractionalOffsetTween( - begin: FractionalOffset.bottomLeft, - end: FractionalOffset.topLeft - ); - _MountainViewPageTransition({ Key key, - Animation animation, + this.routeAnimation, this.child, }) : super( key: key, listenable: _kTween.animate(new CurvedAnimation( - parent: animation, // The route's linear 0.0 - 1.0 animation. + parent: routeAnimation, // The route's linear 0.0 - 1.0 animation. curve: Curves.fastOutSlowIn ) )); + static final FractionalOffsetTween _kTween = new FractionalOffsetTween( + begin: const FractionalOffset(0.0, 0.25), + end: FractionalOffset.topLeft + ); + final Widget child; + final Animation routeAnimation; @override Widget build(BuildContext context) { // TODO(ianh): tell the transform to be un-transformed for hit testing return new SlideTransition( position: listenable, - child: child + child: new FadeTransition( + opacity: new CurvedAnimation( + parent: routeAnimation, + curve: Curves.easeIn, // Eyeballed from other Material apps. + ), + child: child, + ), ); } } @@ -272,7 +279,7 @@ class MaterialPageRoute extends PageRoute { ); } else { return new _MountainViewPageTransition( - animation: animation, + routeAnimation: animation, child: child ); } diff --git a/packages/flutter/test/material/page_test.dart b/packages/flutter/test/material/page_test.dart new file mode 100644 index 0000000000..929dfebfdb --- /dev/null +++ b/packages/flutter/test/material/page_test.dart @@ -0,0 +1,41 @@ +// Copyright 2017 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/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + testWidgets('test Android page transition', (WidgetTester tester) async { + await tester.pumpWidget( + new MaterialApp( + theme: new ThemeData(platform: TargetPlatform.android), + home: new Material(child: new Text('Page 1')), + routes: { + '/next': (BuildContext context) { + return new Material(child: new Text('Page 2')); + }, + } + ) + ); + + final Point widget1TopLeft = tester.getTopLeft(find.text('Page 1')); + + tester.state(find.byType(Navigator)).pushNamed('/next'); + await tester.pump(); + await tester.pump(const Duration(milliseconds: 1)); + + final Opacity widget2Opacity = + tester.element(find.text('Page 2')).ancestorWidgetOfExactType(Opacity); + final Point widget2TopLeft = tester.getTopLeft(find.text('Page 2')); + final Size widget2Size = tester.getSize(find.text('Page 2')); + + expect(widget1TopLeft.x == widget2TopLeft.x, true); + // Page 1 is above page 2 mid-transition. + expect(widget1TopLeft.y < widget2TopLeft.y, true); + // Animation begins 3/4 of the way up the page. + expect(widget2TopLeft.y < widget2Size.height / 4.0, true); + // Animation starts with page 2 being near transparent. + expect(widget2Opacity.opacity < 0.01, true); + }); +}