【移动应用开发技术】怎么给Flutter界面切换实现点特效_第1页
【移动应用开发技术】怎么给Flutter界面切换实现点特效_第2页
【移动应用开发技术】怎么给Flutter界面切换实现点特效_第3页
【移动应用开发技术】怎么给Flutter界面切换实现点特效_第4页
【移动应用开发技术】怎么给Flutter界面切换实现点特效_第5页
已阅读5页,还剩22页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

【移动应用开发技术】怎么给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. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论