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

Support RTL Cupertino nav bar transitions between routes (#23221)

parent 125b5d62
...@@ -1410,8 +1410,8 @@ class _TransitionableNavigationBar extends StatelessWidget { ...@@ -1410,8 +1410,8 @@ class _TransitionableNavigationBar extends StatelessWidget {
class _NavigationBarTransition extends StatelessWidget { class _NavigationBarTransition extends StatelessWidget {
_NavigationBarTransition({ _NavigationBarTransition({
@required this.animation, @required this.animation,
@required _TransitionableNavigationBar topNavBar, @required this.topNavBar,
@required _TransitionableNavigationBar bottomNavBar, @required this.bottomNavBar,
}) : heightTween = Tween<double>( }) : heightTween = Tween<double>(
begin: bottomNavBar.renderBox.size.height, begin: bottomNavBar.renderBox.size.height,
end: topNavBar.renderBox.size.height, end: topNavBar.renderBox.size.height,
...@@ -1423,15 +1423,11 @@ class _NavigationBarTransition extends StatelessWidget { ...@@ -1423,15 +1423,11 @@ class _NavigationBarTransition extends StatelessWidget {
borderTween = BorderTween( borderTween = BorderTween(
begin: bottomNavBar.border, begin: bottomNavBar.border,
end: topNavBar.border, end: topNavBar.border,
),
componentsTransition = _NavigationBarComponentsTransition(
animation: animation,
bottomNavBar: bottomNavBar,
topNavBar: topNavBar,
); );
final Animation<double> animation; final Animation<double> animation;
final _NavigationBarComponentsTransition componentsTransition; final _TransitionableNavigationBar topNavBar;
final _TransitionableNavigationBar bottomNavBar;
final Tween<double> heightTween; final Tween<double> heightTween;
final ColorTween backgroundTween; final ColorTween backgroundTween;
...@@ -1439,6 +1435,13 @@ class _NavigationBarTransition extends StatelessWidget { ...@@ -1439,6 +1435,13 @@ class _NavigationBarTransition extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final _NavigationBarComponentsTransition componentsTransition = _NavigationBarComponentsTransition(
animation: animation,
bottomNavBar: bottomNavBar,
topNavBar: topNavBar,
directionality: Directionality.of(context),
);
final List<Widget> children = <Widget>[ final List<Widget> children = <Widget>[
// Draw an empty navigation bar box with changing shape behind all the // Draw an empty navigation bar box with changing shape behind all the
// moving components without any components inside it itself. // moving components without any components inside it itself.
...@@ -1516,6 +1519,7 @@ class _NavigationBarComponentsTransition { ...@@ -1516,6 +1519,7 @@ class _NavigationBarComponentsTransition {
@required this.animation, @required this.animation,
@required _TransitionableNavigationBar bottomNavBar, @required _TransitionableNavigationBar bottomNavBar,
@required _TransitionableNavigationBar topNavBar, @required _TransitionableNavigationBar topNavBar,
@required TextDirection directionality,
}) : bottomComponents = bottomNavBar.componentsKeys, }) : bottomComponents = bottomNavBar.componentsKeys,
topComponents = topNavBar.componentsKeys, topComponents = topNavBar.componentsKeys,
bottomNavBarBox = bottomNavBar.renderBox, bottomNavBarBox = bottomNavBar.renderBox,
...@@ -1528,7 +1532,8 @@ class _NavigationBarComponentsTransition { ...@@ -1528,7 +1532,8 @@ class _NavigationBarComponentsTransition {
topLargeExpanded = topNavBar.largeExpanded, topLargeExpanded = topNavBar.largeExpanded,
transitionBox = transitionBox =
// paintBounds are based on offset zero so it's ok to expand the Rects. // paintBounds are based on offset zero so it's ok to expand the Rects.
bottomNavBar.renderBox.paintBounds.expandToInclude(topNavBar.renderBox.paintBounds); bottomNavBar.renderBox.paintBounds.expandToInclude(topNavBar.renderBox.paintBounds),
forwardDirection = directionality == TextDirection.ltr ? 1.0 : -1.0;
static final Animatable<double> fadeOut = Tween<double>( static final Animatable<double> fadeOut = Tween<double>(
begin: 1.0, begin: 1.0,
...@@ -1560,6 +1565,9 @@ class _NavigationBarComponentsTransition { ...@@ -1560,6 +1565,9 @@ class _NavigationBarComponentsTransition {
// sizing component of RelativeRects will be based on this rect's size. // sizing component of RelativeRects will be based on this rect's size.
final Rect transitionBox; final Rect transitionBox;
// x-axis unity number representing the direction of growth for text.
final double forwardDirection;
// Take a widget it its original ancestor navigation bar render box and // Take a widget it its original ancestor navigation bar render box and
// translate it into a RelativeBox in the transition navigation bar box. // translate it into a RelativeBox in the transition navigation bar box.
RelativeRect positionInTransitionBox( RelativeRect positionInTransitionBox(
...@@ -1579,8 +1587,8 @@ class _NavigationBarComponentsTransition { ...@@ -1579,8 +1587,8 @@ class _NavigationBarComponentsTransition {
// ancestor navigation bar to another widget's position in that widget's // ancestor navigation bar to another widget's position in that widget's
// navigation bar. // navigation bar.
// //
// Anchor their positions based on the center of their respective render // Anchor their positions based on the vertical middle of their respective
// boxes' leading edge. // render boxes' leading edge.
// //
// Also produce RelativeRects with sizes that would preserve the constant // Also produce RelativeRects with sizes that would preserve the constant
// BoxConstraints of the 'from' widget so that animating font sizes etc don't // BoxConstraints of the 'from' widget so that animating font sizes etc don't
...@@ -1595,7 +1603,11 @@ class _NavigationBarComponentsTransition { ...@@ -1595,7 +1603,11 @@ class _NavigationBarComponentsTransition {
final RenderBox fromBox = fromKey.currentContext.findRenderObject(); final RenderBox fromBox = fromKey.currentContext.findRenderObject();
final RenderBox toBox = toKey.currentContext.findRenderObject(); final RenderBox toBox = toKey.currentContext.findRenderObject();
final Rect toRect =
// We move a box with the size of the 'from' render object such that its
// upper left corner is at the upper left corner of the 'to' render object.
// With slight y axis adjustment for those render objects' height differences.
Rect toRect =
toBox.localToGlobal( toBox.localToGlobal(
Offset.zero, Offset.zero,
ancestor: toNavBarBox, ancestor: toNavBarBox,
...@@ -1604,6 +1616,12 @@ class _NavigationBarComponentsTransition { ...@@ -1604,6 +1616,12 @@ class _NavigationBarComponentsTransition {
- fromBox.size.height / 2 + toBox.size.height / 2 - fromBox.size.height / 2 + toBox.size.height / 2
) & fromBox.size; // Keep the from render object's size. ) & fromBox.size; // Keep the from render object's size.
if (forwardDirection < 0) {
// If RTL, move the center right to the center right instead of matching
// the center lefts.
toRect = toRect.translate(- fromBox.size.width + toBox.size.width, 0.0);
}
return RelativeRectTween( return RelativeRectTween(
begin: fromRect, begin: fromRect,
end: RelativeRect.fromRect(toRect, transitionBox), end: RelativeRect.fromRect(toRect, transitionBox),
...@@ -1666,10 +1684,15 @@ class _NavigationBarComponentsTransition { ...@@ -1666,10 +1684,15 @@ class _NavigationBarComponentsTransition {
final RelativeRect from = positionInTransitionBox(bottomComponents.backLabelKey, from: bottomNavBarBox); final RelativeRect from = positionInTransitionBox(bottomComponents.backLabelKey, from: bottomNavBarBox);
// Transition away by sliding horizontally to the left off of the screen. // Transition away by sliding horizontally to the leading edge off of the screen.
final RelativeRectTween positionTween = RelativeRectTween( final RelativeRectTween positionTween = RelativeRectTween(
begin: from, begin: from,
end: from.shift(Offset(-bottomNavBarBox.size.width / 2.0, 0.0)), end: from.shift(
Offset(
forwardDirection * (-bottomNavBarBox.size.width / 2.0),
0.0,
),
),
); );
return PositionedTransition( return PositionedTransition(
...@@ -1696,6 +1719,7 @@ class _NavigationBarComponentsTransition { ...@@ -1696,6 +1719,7 @@ class _NavigationBarComponentsTransition {
} }
if (bottomMiddle != null && topBackLabel != null) { if (bottomMiddle != null && topBackLabel != null) {
// Move from current position to the top page's back label position.
return PositionedTransition( return PositionedTransition(
rect: animation.drive(slideFromLeadingEdge( rect: animation.drive(slideFromLeadingEdge(
fromKey: bottomComponents.middleKey, fromKey: bottomComponents.middleKey,
...@@ -1722,8 +1746,9 @@ class _NavigationBarComponentsTransition { ...@@ -1722,8 +1746,9 @@ class _NavigationBarComponentsTransition {
); );
} }
// When the top page has a leading widget override, don't move the bottom // When the top page has a leading widget override (one of the few ways to
// middle widget. // not have a top back label), don't move the bottom middle widget and just
// fade.
if (bottomMiddle != null && topLeading != null) { if (bottomMiddle != null && topLeading != null) {
return Positioned.fromRelativeRect( return Positioned.fromRelativeRect(
rect: positionInTransitionBox(bottomComponents.middleKey, from: bottomNavBarBox), rect: positionInTransitionBox(bottomComponents.middleKey, from: bottomNavBarBox),
...@@ -1751,6 +1776,7 @@ class _NavigationBarComponentsTransition { ...@@ -1751,6 +1776,7 @@ class _NavigationBarComponentsTransition {
} }
if (bottomLargeTitle != null && topBackLabel != null) { if (bottomLargeTitle != null && topBackLabel != null) {
// Move from current position to the top page's back label position.
return PositionedTransition( return PositionedTransition(
rect: animation.drive(slideFromLeadingEdge( rect: animation.drive(slideFromLeadingEdge(
fromKey: bottomComponents.largeTitleKey, fromKey: bottomComponents.largeTitleKey,
...@@ -1779,15 +1805,22 @@ class _NavigationBarComponentsTransition { ...@@ -1779,15 +1805,22 @@ class _NavigationBarComponentsTransition {
} }
if (bottomLargeTitle != null && topLeading != null) { if (bottomLargeTitle != null && topLeading != null) {
// Unlike bottom middle, the bottom large title moves when it can't
// transition to the top back label position.
final RelativeRect from = positionInTransitionBox(bottomComponents.largeTitleKey, from: bottomNavBarBox); final RelativeRect from = positionInTransitionBox(bottomComponents.largeTitleKey, from: bottomNavBarBox);
final RelativeRectTween positionTween = RelativeRectTween( final RelativeRectTween positionTween = RelativeRectTween(
begin: from, begin: from,
end: from.shift(Offset(bottomNavBarBox.size.width / 4.0, 0.0)), end: from.shift(
Offset(
forwardDirection * bottomNavBarBox.size.width / 4.0,
0.0,
),
),
); );
// Just shift slightly towards the right instead of moving to the back // Just shift slightly towards the trailing edge instead of moving to the
// label position. // back label position.
return PositionedTransition( return PositionedTransition(
rect: animation.drive(positionTween), rect: animation.drive(positionTween),
child: FadeTransition( child: FadeTransition(
...@@ -1851,7 +1884,12 @@ class _NavigationBarComponentsTransition { ...@@ -1851,7 +1884,12 @@ class _NavigationBarComponentsTransition {
// right. // right.
if (bottomBackChevron == null) { if (bottomBackChevron == null) {
final RenderBox topBackChevronBox = topComponents.backChevronKey.currentContext.findRenderObject(); final RenderBox topBackChevronBox = topComponents.backChevronKey.currentContext.findRenderObject();
from = to.shift(Offset(topBackChevronBox.size.width * 2.0, 0.0)); from = to.shift(
Offset(
forwardDirection * topBackChevronBox.size.width * 2.0,
0.0,
),
);
} }
final RelativeRectTween positionTween = RelativeRectTween( final RelativeRectTween positionTween = RelativeRectTween(
...@@ -1967,7 +2005,12 @@ class _NavigationBarComponentsTransition { ...@@ -1967,7 +2005,12 @@ class _NavigationBarComponentsTransition {
// Shift in from the trailing edge of the screen. // Shift in from the trailing edge of the screen.
final RelativeRectTween positionTween = RelativeRectTween( final RelativeRectTween positionTween = RelativeRectTween(
begin: to.shift(Offset(topNavBarBox.size.width / 2.0, 0.0)), begin: to.shift(
Offset(
forwardDirection * topNavBarBox.size.width / 2.0,
0.0,
),
),
end: to, end: to,
); );
...@@ -2010,7 +2053,12 @@ class _NavigationBarComponentsTransition { ...@@ -2010,7 +2053,12 @@ class _NavigationBarComponentsTransition {
// Shift in from the trailing edge of the screen. // Shift in from the trailing edge of the screen.
final RelativeRectTween positionTween = RelativeRectTween( final RelativeRectTween positionTween = RelativeRectTween(
begin: to.shift(Offset(topNavBarBox.size.width, 0.0)), begin: to.shift(
Offset(
forwardDirection * topNavBarBox.size.width,
0.0,
),
),
end: to, end: to,
); );
......
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