版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
【移动应用开发技术】怎么给Flutter界面切换实现点特效
在下给大家分享一下怎么给Flutter界面切换实现点特效,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!背景我们知道页面之间如果直接切换,会比较生硬,还会让用户觉得很突兀,用户体验不是很好。因此一般情况下,页面之间的切换为了达到平滑过渡,都会添加动画。另外,有时候我们不喜欢系统的默认动画,希望能够自定义动画。基于此,本篇主要讲述如何给Flutter的页面切换增加自定义动画。默认效果首先我们看看默认效果是怎样的?看起来似乎还不错。代码如下:import
'package:flutter/material.dart';
void
main()
=>
runApp(MaterialApp(
home:
MyApp(),
));
class
MyApp
extends
StatelessWidget
{
//
This
widget
is
the
root
of
your
application.
@override
Widget
build(BuildContext
context)
{
return
_getCenterWidget(RaisedButton(
child:
Text('Go
to
next
>'),
onPressed:
()
{
Navigator.of(context).push(_createRoute());
}));
}
}
Route
_createRoute()
{
return
MaterialPageRoute(builder:
(BuildContext
context)
=>
Page2());
}
class
Page2
extends
StatelessWidget
{
@override
Widget
build(BuildContext
context)
{
return
_getCenterWidget(Text('Page2'));
}
}
Widget
_getCenterWidget(Widget
child)
{
return
Scaffold(
appBar:
AppBar(),
body:
Center(
child:
child,
),
);
}可以看到创建了两个页面MyApp和Page2。第一个页面MyApp有一个按钮,第二个页面Page2有一个文本。关键的切换就在_createRoute()这个路由创建方法里面。我们点进去MaterialPageRoute源码,可以看到
@override
Widget
buildTransitions(BuildContext
context,
Animation<double>
animation,
Animation<double>
secondaryAnimation,
Widget
child)
{
final
PageTransitionsTheme
theme
=
Theme.of(context).pageTransitionsTheme;
return
theme.buildTransitions<T>(this,
context,
animation,
secondaryAnimation,
child);
}加上一开始的注释,可以知道这个就是默认的界面切换过渡效果。///
See
also:
///
///
*
[PageTransitionsTheme],
which
defines
the
default
page
transitions
used
///
by
[MaterialPageRoute.buildTransitions].另外这里可以看到默认的动画时长为300ms,而且我们不能自定义。
@override
Duration
get
transitionDuration
=>
const
Duration(milliseconds:
300);接下来我们就说说如何自定义我们的界面切换过渡效果,并且自定义动画时长。自定义动画1.设置PageRouteBuilder由上面的分析我们知道最关键的地方在创建路由方法_createRoute()中。因此我们首先修改一下,不使用默认的MaterialPageRoute,我们使用PageRouteBuilder。Route
_createRoute()
{
return
PageRouteBuilder(
pageBuilder:
(context,
animation,
secondaryAnimation)
=>
Page2(),
transitionsBuilder:(context,
animation,
secondaryAnimation,
child)
{
return
child;
}
);
}可以看到我们通过pageBuilder指定路由页面,通过transitionsBuilder指定页面过渡效果。另外说明一下,这里的参数大家不用死记硬背,我们点进去源码一看就知道了,如下:///
Signature
for
the
function
that
builds
a
route's
primary
contents.
///
Used
in
[PageRouteBuilder]
and
[showGeneralDialog].
///
///
See
[ModalRoute.buildPage]
for
complete
definition
of
the
parameters.
typedef
RoutePageBuilder
=
Widget
Function(BuildContext
context,
Animation<double>
animation,
Animation<double>
secondaryAnimation);
///
Signature
for
the
function
that
builds
a
route's
transitions.
///
Used
in
[PageRouteBuilder]
and
[showGeneralDialog].
///
///
See
[ModalRoute.buildTransitions]
for
complete
definition
of
the
parameters.
typedef
RouteTransitionsBuilder
=
Widget
Function(BuildContext
context,
Animation<double>
animation,
Animation<double>
secondaryAnimation,
Widget
child);如果我们运行代码,由于直接返回child,所以应该是没有动画效果的。我们运行之后,效果如下:2.添加Tween和SlideTransition默认的过渡效果是从右边往左过来,我们这里自定义的演示效果就从下面往上过渡好了。需要了解一下的是Tween是一个介于开始和结束值的线性插值器。另外我们跟进上面的transitionsBuilder可以知道他的第一个animation参数取值为0.0到1.0。我们这边是从下往上,所以y轴的偏移就是由1.0到0.0,表示竖直方向距离顶部一整个页面到不存在偏移(已经在顶部)。因此关于Tween和animation我们可以得到:var
begin
=
Offset(0.0,
1.0);
var
end
=
Offset(0.0,
0.0);
var
tween
=
Tween(begin:
begin,
end:
end);
var
offsetAnimation
=
animation.drive(tween);因为我们是要实现滑动,因此将这个确定好的偏移动画通过SlideTransition处理并返回,可以得到修改后的路由代码如下:Route
_createRoute()
{
return
PageRouteBuilder(
transitionDuration:
Duration(seconds:
5),
pageBuilder:
(context,
animation,
secondaryAnimation)
=>
Page2(),
transitionsBuilder:(context,
animation,
secondaryAnimation,
child)
{
var
begin
=
Offset(0.0,
1.0);
var
end
=
Offset(0.0,
0.0);
var
tween
=
Tween(begin:
begin,
end:
end);
var
offsetAnimation
=
animation.drive(tween);
return
SlideTransition(
position:
offsetAnimation,
child:
child,
);
}
);
}效果如下:看到上面效果,可能有小伙伴会有疑问。问题一:你打开页面是从下到上我可以理解,但是返回为什么是反过来的从上到下呢?我们跟进去transitionsBuilder的源码,可以看到
///
Used
to
build
the
route's
transitions.
///
///
See
[ModalRoute.buildTransitions]
for
complete
definition
of
the
parameters.
final
RouteTransitionsBuilder
transitionsBuilder;我们跟进去(通过点击)注释里面的buildTransitions,可以看到animation的说明如下:
///
*
[animation]:
When
the
[Navigator]
pushes
a
route
on
the
top
of
its
stack,
///
the
new
route's
primary
[animation]
runs
from
0.0
to
1.0.
When
the
[Navigator]
///
pops
the
topmost
route
this
animation
runs
from
1.0
to
0.0.可以看到入栈和出栈的动画效果是相反的,而这个也符合我们的认知。问题二:现在的效果是从下到上,如果我要实现从上到下,是不是将begin和end的Offset交换一下就可以?其实如果你理解我上面说的这句话我们这边是从下往上,所以y轴的偏移就是由1.0到0.0,表示竖直方向距离顶部一整个页面到不存在偏移(已经在顶部)。我们这边是从下往上,所以y轴的偏移就是由1.0到0.0,表示竖直方向距离顶部一整个页面到不存在偏移(已经在顶部)。你就会知道,改成从0.0到1.0会是什么情况。我们改一下,通过实际演示效果来说明。修改后的代码如下:Route
_createRoute()
{
return
PageRouteBuilder(
pageBuilder:
(context,
animation,
secondaryAnimation)
=>
Page2(),
transitionsBuilder:(context,
animation,
secondaryAnimation,
child)
{
var
begin
=
Offset(0.0,
0.0);
var
end
=
Offset(0.0,
1.0);
var
tween
=
Tween(begin:
begin,
end:
end);
var
offsetAnimation
=
animation.drive(tween);
return
SlideTransition(
position:
offsetAnimation,
child:
child,
);
}
);
}仅仅是begin和end的Offset做了交换。运行效果如下:虽然能够看出一点端倪,但是我们前面讲过,默认动画时长是300ms,所以比较快,这样不好分析。我们可以通过PageRouteBuilder的transitionDuration属性来设置动画的时长。我们设置3s来看下效果,代码如下:Route
_createRoute()
{
return
PageRouteBuilder(
transitionDuration:
Duration(seconds:
3),
pageBuilder:
(context,
animation,
secondaryAnimation)
=>
Page2(),
transitionsBuilder:(context,
animation,
secondaryAnimation,
child)
{
var
begin
=
Offset(0.0,
0.0);
var
end
=
Offset(0.0,
1.0);
var
tween
=
Tween(begin:
begin,
end:
end);
var
offsetAnimation
=
animation.drive(tween);
return
SlideTransition(
position:
offsetAnimation,
child:
child,
);
}
);
}运行效果如下:看到了吧,确实是反过来了,从一开始距离顶部为0.0,到距离顶部1.0(100%)。那么如果我想实现从上到下进入怎么办呢?我们给一张图,相信看完你就懂了。从这张图我们知道,如果我们从下往上,y应该从1.0变到0.0。如果要从上往下,y应该从-1.0变到0.0。所以我们修改代码,如下:Route
_createRoute()
{
return
PageRouteBuilder(
transitionDuration:
Duration(seconds:
3),
pageBuilder:
(context,
animation,
secondaryAnimation)
=>
Page2(),
transitionsBuilder:(context,
animation,
secondaryAnimation,
child)
{
var
begin
=
Offset(0.0,
-1.0);
var
end
=
Offset(0.0,
0.0);
var
tween
=
Tween(begin:
begin,
end:
end);
var
offsetAnimation
=
animation.drive(tween);
return
SlideTransition(
position:
offsetAnimation,
child:
child,
);
}
);
}运行效果为:3.通过CurveTween来点加速度当我们将动画时长设置为3s之后,我们可以明显的看到我们的动画速度似乎是匀速的。那么如果我想修改下动画的速度,比如进来快,结束慢,可不可以呢?答案是肯定的。我们通过CurveTween可以来实现这个需求。使用的重点在于curve的选择,所以我们要选择哪种curve呢?其实Flutter我比较喜欢的一个点就是代码注释详细,并且还有demo演示。我们进入Curves源码,以Curves.ease为例:
///
A
cubic
animation
curve
that
speeds
up
quickly
and
ends
slowly.
///
///
{@animation
464
192
https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease.mp4}
static
const
Cubic
ease
=
Cubic(0.25,
0.1,
0.25,
1.0);注释说了启动快,结束慢,而且还有一个mp4链接,点击可以看到如下效果:我们可以看出它的变化趋势,通过斜率可以看出前期快,后期慢,而且右边还有四种动画的效果预览。我们设置CurveTween代码如下:var
curveTween
=
CurveTween(curve:
Curves.ease);可以看到很简单,选择一种你想要的变化趋势即可。4.组合Tween和CurveTween这个也比较简单,通过Tween自带的chain方法即可,如下:var
tween
=
Tween(begin:
begin,
end:
end).chain(CurveTween(curve:
Curves.ease));另外一般Offset(0.0,0.0)可以直接写为Offset.zero。修改后代码为:Route
_createRoute()
{
return
PageRouteBuilder(
transitionDuration:
Duration(seconds:
3),
pageBuilder:
(context,
animation,
secondaryAnimation)
=>
Page2(),
transitionsBuilder:(context,
animation,
secondaryAnimation,
child)
{
var
begin
=
Offset(0.0,
1.0);
var
end
=
Offset.zero;
var
tween
=
Tween(begin:
begin,
end:
end).chain(CurveTween(curve:
Curves.ease));
return
SlideTransition(
position:
animation.drive(tween),
child:
child,
);
}
);
}运行效果如下:5.完整例子有了上面的基础,我们就可以将四个方向的动画效果都加上,当然我们这边就不延时了。另外为了演示方便,就直接打开后delay1s返回。代码如下:import
'package:flutter/material.dart';
void
main()
=>
runApp(MaterialApp(
home:
MyApp(),
));
class
MyApp
extends
StatelessWidget
{
//
This
widget
is
the
root
of
your
application.
@override
Widget
build(BuildContext
context)
{
return
_getCenterWidget(Column(
mainAxisAlignment:
MainAxisAlignment.center,
children:
<Widget>[
_getBtn(context,
'right
in',
Tween(begin:
Offset(1.0,
0.0),
end:
Offset.zero)),
_getBtn(context,
'left
in',
Tween(begin:
Offset(-1.0,
0.0),
end:
Offset.zero)),
_getBtn(context,
'bottom
in',
Tween(begin:
Offset(0.0,
1.0),
end:
Offset.zero)),
_getBtn(context,
'top
in',
Tween(begin:
Offset(0.0,
-1.0),
end:
Offset.zero)),
],
));
}
}
Widget
_getBtn(BuildContext
context,
String
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024-2030年中国酱醋生产基地行业发展分析及投资风险预警与发展策略研究报告
- 幼儿园大班教案端午节教案7篇
- 2024-2030年中国酒产品行业市场发展分析及前景趋势与投资研究报告
- 2024-2030年中国邻-硝基苯甲醚融资商业计划书
- 2024-2030年中国逻辑电路行业市场发展分析及前景趋势与投资研究报告
- 2024-2030年中国速冻小吃行业市场发展趋势与前景展望战略分析报告
- 2024-2030年中国迷你无线耳机行业销售态势与营销趋势预测报告
- 2024-2030年中国远程现场测试系统行业发展状况与投资规划分析报告
- 2024-2030年中国运输行业市场发展现状及消费需求与投资前景研究报告
- 2024-2030年中国达马胶行业销售态势与竞争趋势预测报告
- 幼儿园大班数学《风车转转转》课件
- 《汽车电气设备构造与维修中职版》课程标准
- 《简笔画》课程标准
- 医学影像诊断学智慧树知到课后章节答案2023年下湖北科技学院
- CMK自动计算公式表格模板
- 小学生主题班会 少先队队前教育(课件)(共25张PPT)
- 某35kv变电站整套施工组织设计方案
- 《我骄傲我是中国人》原文
- 同条件混凝土试块600度天温度记录累计自动计算表格
- NB/T 11126-2023煤矿用主动式隔抑爆装置应用技术规范
- 大数据营销屈莉莉课后参考答案
评论
0/150
提交评论