flutter - 如何根据下一条路线自定义传出动画?
问题描述
我想要的是:
我的场景分为两部分:按钮栏和内容。我想要类似于 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
解决方案
推荐阅读
- sql - 使用列与时间的差异时的case语句错误
- html - 属性显示的媒体查询问题:无;
- reactjs - 如何从浏览器控制台访问 React 和 ReactDOM?
- android - 如何使用浮动操作按钮创建底部导航
- mysql - PHPMyAdmin 替换 url 中的查询值
- angular - Angular Ionic CSS 未应用
- java - 是否可以在没有相应属性的情况下将方法返回值存储在数据库中?
- javascript - 如果 URL 相同,则反应路由器 dom history.replace 不会重新渲染组件
- javascript - 如何让不和谐机器人编辑 dm 消息?
- command-line - 如何仅将时间戳与 WinSCP 同步?