Unverified Commit 5eaaad41 authored by chunhtai's avatar chunhtai Committed by GitHub

fix cupertino page route dismisses hero transition when swipe to the … (#58024)

* fix cupertino page route dismisses hero transition when swipe to the edge

* add more comment

* addressing comments
parent 82187e6b
......@@ -533,6 +533,14 @@ class _HeroFlight {
}
void _handleAnimationUpdate(AnimationStatus status) {
// The animation will not finish until the user lifts their finger, so we
// should ignore the status update if the gesture is in progress.
//
// This also relies on the animation to update its status at the end of the
// gesture. See the _CupertinoBackGestureController.dragEnd for how
// cupertino page route achieves that.
if (manifest.fromRoute?.navigator?.userGestureInProgress == true)
return;
if (status == AnimationStatus.completed || status == AnimationStatus.dismissed) {
_proxyAnimation.parent = null;
......
......@@ -1133,6 +1133,76 @@ void main() {
expect(nestedObserver.popupCount, 0);
});
testWidgets('back swipe to screen edges does not dismiss the hero animation', (WidgetTester tester) async {
final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
final UniqueKey container = UniqueKey();
await tester.pumpWidget(CupertinoApp(
navigatorKey: navigator,
routes: <String, WidgetBuilder>{
'/': (BuildContext context) {
return CupertinoPageScaffold(
child: Center(
child: Hero(
tag: 'tag',
transitionOnUserGestures: true,
child: Container(key: container, height: 150.0, width: 150.0)
),
)
);
},
'/page2': (BuildContext context) {
return CupertinoPageScaffold(
child: Center(
child: Padding(
padding: const EdgeInsets.fromLTRB(100.0, 0.0, 0.0, 0.0),
child: Hero(
tag: 'tag',
transitionOnUserGestures: true,
child: Container(key: container, height: 150.0, width: 150.0)
)
),
)
);
}
},
));
RenderBox box = tester.renderObject(find.byKey(container)) as RenderBox;
final double initialPosition = box.localToGlobal(Offset.zero).dx;
navigator.currentState.pushNamed('/page2');
await tester.pumpAndSettle();
box = tester.renderObject(find.byKey(container)) as RenderBox;
final double finalPosition = box.localToGlobal(Offset.zero).dx;
final TestGesture gesture = await tester.startGesture(const Offset(5, 300));
await gesture.moveBy(const Offset(200, 0));
await tester.pump();
box = tester.renderObject(find.byKey(container)) as RenderBox;
final double firstPosition = box.localToGlobal(Offset.zero).dx;
// Checks the hero is in-transit.
expect(finalPosition, greaterThan(firstPosition));
expect(firstPosition, greaterThan(initialPosition));
// Goes back to final position.
await gesture.moveBy(const Offset(-200, 0));
await tester.pump();
box = tester.renderObject(find.byKey(container)) as RenderBox;
final double secondPosition = box.localToGlobal(Offset.zero).dx;
// There will be a small difference.
expect(finalPosition - secondPosition, lessThan(0.001));
await gesture.moveBy(const Offset(400, 0));
await tester.pump();
box = tester.renderObject(find.byKey(container)) as RenderBox;
final double thirdPosition = box.localToGlobal(Offset.zero).dx;
// Checks the hero is still in-transit and moves further away from the first
// position.
expect(finalPosition, greaterThan(thirdPosition));
expect(thirdPosition, greaterThan(initialPosition));
expect(firstPosition, greaterThan(thirdPosition));
});
testWidgets('showCupertinoModalPopup uses nested navigator if useRootNavigator is false', (WidgetTester tester) async {
final PopupObserver rootObserver = PopupObserver();
final PopupObserver nestedObserver = PopupObserver();
......
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