我想要的是:
我的场景分为两部分:按钮栏和内容。我想要类似于 Android ViewPager 行为的东西:当我点击一个按钮时,相应的场景会从左侧或右侧滑入,具体取决于按钮栏中的按钮位置:
______________________________
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|______________________________|
| | | |
| Discover | TV Shows | Movies |
|__________|__________|________|
例如,当从Discover导航到TV Shows时,TV Shows场景应该从右侧滑动,同时Discover场景应该向左移动。
请注意,中间项目TV Shows可以有不同的过渡,这取决于我们来自哪里:
- 从Discover到TV Shows --> TV Shows场景应该来自右边
- 从电影到电视节目-->电视节目场景应该来自左边
我做了什么:
我创建了自己的 PageRoute,并在其中覆盖了该buildTransitions
方法。我有一点逻辑来确定幻灯片动画的方向:
import 'package:flutter/material.dart';
class CustomPageRoute<T> extends MaterialPageRoute<T> {
final String currentTab;
final String newTab;
final Widget child;
CustomPageRoute(this.currentTab, this.newTab, this.child) : super(builder: (BuildContext context) => child);
@override
Widget buildTransitions(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) {
if (currentTab == null) {
// First scene of the Navigator, use the theme (FadeTransition)
return super.buildTransitions(context, animation, secondaryAnimation, child);
}
Offset startPosition;
switch ('$currentTab-->$newTab') {
case '/-->/tvshow':
case '/-->/movie':
case '/tvshow-->/movie':
// If the button is on the right in the tab bar, the scene will come from the right
startPosition = Offset(1.0, 0.0);
break;
case '/tvshow-->/':
case '/movie-->/':
case '/movie-->/tvshow':
// If the button is on the left in the tab bar, the scene will come from the left
startPosition = Offset(-1.0, 0.0);
break;
default:
startPosition = Offset.zero;
}
return SlideTransition(
position: Tween<Offset>(
begin: startPosition,
end: Offset.zero,
).animate(animation),
child: child,
);
}
}
onGenerateRoute
我的用法Navigator
:
onGenerateRoute: (RouteSettings settings) {
Widget widget;
switch (settings.name) {
case '/':
widget = DiscoverTab();
break;
case '/tvshow':
widget = TvShowTab();
break;
case '/movie':
widget = MovieTab();
break;
default:
throw Exception('Invalid route: ${settings.name}');
}
CustomPageRoute route = CustomPageRoute(this.lastRoute, settings.name, widget);
// Save the route for the next one
this.lastRoute = settings.name;
return route;
}
问题:
传入场景来自正确的一侧(从左到右),但传出场景保持原位。所以传入的场景正在“覆盖”传出的场景。
外观和感觉还不错,但它不是理想的结果:
我希望传出场景以相反的方向移出屏幕,以便像真正的滑块一样将位置留给传入场景。因此,我还必须通过参数为即将传出的场景设置动画secondaryAnimation
。
我可以编写 2 个动画,如下所示:
SlideTransition(
position: new Tween<Offset>(
begin: Offset(1.0, 0.0),
end: Offset.zero,
).animate(animation), // Incoming scene from right
child: new SlideTransition(
position: new Tween<Offset>(
begin: Offset.zero,
end: Offset(-1.0, 0.0),
).animate(secondaryAnimation), // Outgoing scene to the left
child: child,
),
);
除了中间电视节目场景外,它将工作,因为它可以根据下一条路线有 2 种不同的过渡:在路线创建时方向未知。只有在创建下一条路线时才能知道。
所以我的问题是:在创建新路由时,是否可以访问当前路由的传出转换定义并重新定义它?
我最好的线索是TransitionRoute类中_updateSecondaryAnimation
调用的方法,但我不知道如何使用它。didChangeNext