Unverified Commit e32e4479 authored by xster's avatar xster Committed by GitHub

Add HeroController to CupertinoApp (#19326)

parent 8359d99e
......@@ -42,6 +42,9 @@ const TextStyle _kDefaultTextStyle = const TextStyle(
/// If [home], [routes], [onGenerateRoute], and [onUnknownRoute] are all null,
/// and [builder] is not null, then no [Navigator] is created.
///
/// This widget also configures the observer of the top-level [Navigator] (if
/// any) to perform [Hero] animations.
///
/// Using this widget with caution on Android since it may produce behaviors
/// Android users are not expecting such as:
///
......@@ -171,7 +174,7 @@ class CupertinoApp extends StatefulWidget {
/// When a named route is pushed with [Navigator.pushNamed], the route name is
/// looked up in this map. If the name is present, the associated
/// [WidgetBuilder] is used to construct a [CupertinoPageRoute] that performs
/// an appropriate transition to the new route.
/// an appropriate transition, including [Hero] animations, to the new route.
///
/// If the app only has one page, then you can specify it using [home] instead.
///
......@@ -246,8 +249,8 @@ class CupertinoApp extends StatefulWidget {
///
/// Unless a [Navigator] is provided, either implicitly from [builder] being
/// null, or by a [builder] including its `child` argument, or by a [builder]
/// explicitly providing a [Navigator] of its own, APIs such as
/// [Navigator.push] and [Navigator.pop], will not function.
/// explicitly providing a [Navigator] of its own, widgets and APIs such as
/// [Hero], [Navigator.push] and [Navigator.pop], will not function.
final TransitionBuilder builder;
/// {@macro flutter.widgets.widgetsApp.title}
......@@ -317,9 +320,13 @@ class _AlwaysCupertinoScrollBehavior extends ScrollBehavior {
}
class _CupertinoAppState extends State<CupertinoApp> {
HeroController _heroController;
List<NavigatorObserver> _navigatorObservers;
@override
void initState() {
super.initState();
_heroController = new HeroController(); // Linear tweening.
_updateNavigator();
}
......@@ -335,6 +342,9 @@ class _CupertinoAppState extends State<CupertinoApp> {
widget.routes.isNotEmpty ||
widget.onGenerateRoute != null ||
widget.onUnknownRoute != null;
_navigatorObservers =
new List<NavigatorObserver>.from(widget.navigatorObservers)
..add(_heroController);
}
Widget defaultBuilder(BuildContext context, Widget child) {
......@@ -351,7 +361,7 @@ class _CupertinoAppState extends State<CupertinoApp> {
routes: widget.routes,
onGenerateRoute: widget.onGenerateRoute,
onUnknownRoute: widget.onUnknownRoute,
navigatorObservers: widget.navigatorObservers,
navigatorObservers: _navigatorObservers,
);
if (widget.builder != null) {
return widget.builder(context, navigator);
......
// Copyright 2018 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/cupertino.dart';
void main() {
testWidgets('Heroes work', (WidgetTester tester) async {
await tester.pumpWidget(new CupertinoApp(
home:
new ListView(
children: <Widget>[
const Hero(tag: 'a', child: const Text('foo')),
new Builder(builder: (BuildContext context) {
return new CupertinoButton(
child: const Text('next'),
onPressed: () {
Navigator.push(
context,
new CupertinoPageRoute<void>(
builder: (BuildContext context) {
return const Hero(tag: 'a', child: const Text('foo'));
}
),
);
},
);
}),
],
)
));
await tester.tap(find.text('next'));
await tester.pump();
await tester.pump(const Duration(milliseconds: 100));
// During the hero transition, the hero widget is lifted off of both
// page routes and exists as its own overlay on top of both routes.
expect(find.widgetWithText(CupertinoPageRoute, 'foo'), findsNothing);
expect(find.widgetWithText(Navigator, 'foo'), findsOneWidget);
});
}
\ No newline at end of file
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