主动画 (Hero animations)

你将会在这里学到:

What you’ll learn

Hero 指的是在屏幕间飞跃的 widget。

The hero refers to the widget that flies between screens.

用 Flutter’s Hero widget 创建 hero 动画。

Create a hero animation using Flutter’s Hero widget.

使 hero 从原页面飞至新页面。

Fly the hero from one screen to another.

当 hero 从原页面飞至新页面时,使 hero 的形状由圆形动态过渡为正方形。

Animate the transformation of a hero’s shape from circular to

rectangular while flying it from one screen to another.

Flutter 中的 Hero widget 实现的动画类型也称为 共享元素过渡 或 共享元素动画。

The Hero widget in Flutter implements a style of animation

commonly known as shared element transitions or

shared element animations.

你可能经常遇到 hero 动画。比如,页面上显示的代售商品列表。选择一件商品后,应用会跳转至包含更多细节以及“购买”按钮的新页面。在 Flutter 中,图像从当前页面转到另一个页面称为 hero 动画,相同的动作有时也被称为 共享元素过渡。

You’ve probably seen hero animations many times. For example, a screen displays

a list of thumbnails representing items for sale. Selecting an item flies it to

a new screen, containing more details and a “Buy” button. Flying an image from

one screen to another is called a hero animation in Flutter, though the same

motion is sometimes referred to as a shared element transition.

下面的一分钟视频介绍了 Hero widget:

You might want to watch this one-minute video introducing the Hero widget:

这个指南演示了如何创建标准 hero 动画,以及 hero 动画如何在飞行过程中将图像形状由圆形变成正方形。

This guide demonstrates how to build standard hero animations, and hero

animations that transform the image from a circular shape to a square shape

during flight.

刚接触 Flutter?

New to Flutter?

这部分假定您已经了解如何使用 Flutter 的 widget 创建布局。更多信息请参考文档 Flutter 中的布局。

This page assumes you know how to create a layout

using Flutter’s widgets. For more information, see

Building Layouts in Flutter.

术语:

Terminology:

在 Flutter app 中,Route 用来描述一个页面。

A Route describes a page or screen

in a Flutter app.

您可以在 Flutter 中使用 Hero widgets 创建这个动画。当 hero 动画从原页面到目标页面,目标页面(减去 hero)淡入视野。可以说,heroes 是 UI 的一小部分,就像图像,两个页面有共同之处。从用户的角度来说,hero 在页面间“飞翔”。本指南展示如何创建如下 hero 动画:

You can create this animation in Flutter with Hero widgets.

As the hero animates from the source to the destination route,

the destination route (minus the hero) fades into view.

Typically, heroes are small parts of the UI, like images,

that both routes have in common. From the user’s perspective

the hero “flies” between the routes. This guide shows how

to create the following hero animations:

标准 hero 动画

Standard hero animations

一个 标准 hero 动画 使 hero 从一页飞至新页面,通常以不同大小到达不同的目的地。

A standard hero animation flies the hero from one route to a new route,

usually landing at a different location and with a different size.

下面的视频(慢放)演示了一个典型示例。点击页面中间的 flippers,它将飞至一个新的蓝色页面的左上角,并缩小。点击蓝色页面中的 flippers(或者使用设备的回到前页手势),它将返回原页面。

The following video (recorded at slow speed) shows a typical example.

Tapping the flippers in the center of the route flies them to the

upper left corner of a new, blue route, at a smaller size.

Tapping the flippers in the blue route (orusing the device’s back-to-previous-route gesture) flies the flippers back to

the original route.

径向 hero 动画

Radial hero animations

在 径向 hero 动画 中,随着 hero 在页面间飞翔,它的形状也会有圆形变成矩形。

In radial hero animation, as the hero flies between routes

its shape appears to change from circular to rectangular.

下面的视频(慢放)演示了一个径向 hero 动画的示例。开始,一排三个圆形的图像在页面底部。点击任意圆形图像,其飞至新页面,并变成正方形。点击正方形图像,hero 返回至原页面,并变回圆形。

The following video (recorded at slow speed),

shows an example of a radial hero animation. At the start, a

row of three circular images appears at the bottom of the route.

Tapping any of the circular images flies that image to a new route

that displays it with a square shape.

Tapping the square image flies the hero back to

the original route, displayed with a circular shape.

在学习 标准 或

径向 hero 动画之前,请阅读 hero 动画基本结构 来学习如何构建 hero 动画代码,以及 幕后 来了解 Flutter 如何显示一个 hero 动画。

Before moving to the sections specific to

standard

or radial hero animations,

read basic structure of a hero animation

to learn how to structure hero animation code,

and behind the scenes to understand

how Flutter performs a hero animation.

hero 动画基本结构

Basic structure of a hero animation

要点列表

What's the point?

在不同页面分别使用两个 hero widgets,同时使用配对的标签来实现动画。

Use two hero widgets in different routes but with matching tags to

implement the animation.

Navigator 管理含有 app 页面的堆栈。

The Navigator manages a stack containing the app’s routes.

推送一个页面或弹出一个 Navigator 堆栈中的页面会触发动画。

Pushing a route on or popping a route from the Navigator’s stack

triggers the animation.

Flutter 框架设置了一个 RectTween 类,用来定义 hero 从原页面飞至目标页面的边界。在飞翔过程中,hero 移动到一个应用图层,这样它可以在两个页面上方显示。

The Flutter framework calculates a rectangle tween,

RectTween that defines the hero’s boundary

as it flies from the source to the destination route.

During its flight, the hero is moved to

an application overlay, so that it appears on top of both routes.

术语:

If the concept of tweens or tweening is new to you, see the

Animations in Flutter tutorial.

如果您不了解 tween 或者 tweening 的概念,请参考教程

在 Flutter 应用里实现动画效果

Terminology:

Hero 动画需要使用两个

Hero widgets 来实现:一个用来在原页面中描述 widget,另一个在目标页面中描述 widget。从用户角度来说,hero 似乎是分享的,只有程序员需要了解实施细节。

Hero animations are implemented using two Hero

widgets: one describing the widget in the source route,

and another describing the widget in the destination route.

From the user’s point of view, the hero appears to be shared, and

only the programmer needs to understand this implementation detail.

注意对话框:

Note about dialogs:

Heroes 从一个页面飞至另一个。对话框(例如,显示 showDialog()),使用 PopupRoutes,而不是 PageRoutes。至少现在不是,您无法在对话框中使用 hero 动画。更多内容(和可能的替代方法),

请参考这里

Heroes fly from one PageRoute to another. Dialogs

(displayed with showDialog(), for example), use PopupRoutes,

which are not PageRoutes. At least for now,

you can’t animate a hero to a Dialog.

For further developments (and a possible workaround),

watch this issue.

Hero 动画代码有如下结构:

Hero animation code has the following structure:

定义一个起始 Hero widget,被称为 source hero。该 hero 指定图形表示(通常是图像),以及识别标签,并且在由原页面定义的当前显示的 widget 树中。

Define a starting Hero widget, referred to as the source

hero. The hero specifies its graphical representation

(typically an image), and an identifying tag, and is in

the currently displayed widget tree as defined by the source route.

定义一个截至 Hero widget,被称为 destination hero。该 hero 也指定图形表示,并与 source hero 使用同样的标签。

这是基本,两个 hero widgets 要创建相同的标签,通常是代表基础数据的对象。为了获得最佳效果,heroes 应该有几乎完全相同的 widget 树。

Define an ending Hero widget, referred to as the destination hero.

This hero also specifies its graphical representation,

and the same tag as the source hero.

It’s essential that both hero widgets are created with

the same tag, typically an object that represents the

underlying data. For best results, the heroes should have

virtually identical widget trees.

创建一个含有 destination hero 的页面。目标页面定义了动画结束时应有的 widget 树。

Create a route that contains the destination hero.

The destination route defines the widget tree that exists

at the end of the animation.

通过推送目标页面到 Navigator 堆栈来触发动画。

Navigator 推送并弹出操作触发原页面和目标页面中含有配对标签 heroes 的 hero 动画。

Trigger the animation by pushing the destination route on the

Navigator’s stack. The Navigator push and pop operations trigger

a hero animation for each pair of heroes with matching tags in

the source and destination routes.

Flutter 设置了 tween 用来界定 Hero

从起点到终点的界限(插入大小和位置),并在图层上执行动画。

Flutter calculates the tween that animates the Hero’s bounds from

the starting point to the endpoint (interpolating size and position),

and performs the animation in an overlay.

下一章节将更详细地介绍 Flutter 的过程。

The next section describes Flutter’s process in greater detail.

幕后

Behind the scenes

下面将介绍 Flutter 如何执行一个页面到另一页面的过渡。

The following describes how Flutter performs the

transition from one route to another.

过渡前,source hero 在原页面的 widget 树中等待。而目标页面此时并不存在,图层也是空的。

Before transition, the source hero waits in the source

route’s widget tree. The destination route does not yet exist,

and the overlay is empty.

推送一个页面到 Navigator 来触发动画。t=0.0 时,Flutter 执行如下动作:

Pushing a route to the Navigator triggers the animation.

At t=0.0, Flutter does the following:

使用 Material motion spec 中介绍的曲线运动计算

destination hero 路径,后台运行。

Flutter 限制知道 hero 应在何处终止。

Calculates the destination hero’s path, offscreen,

using the curved motion as described in the Material

motion spec. Flutter now knows where the hero ends up.

将 destination hero 放到图层,与 source hero 相同的位置和大小。添加一个 hero 到图层改变其 Z-order,这样才可以出现在所有页面的上面。

Places the destination hero in the overlay,

at the same location and size as the source hero.

Adding a hero to the overlay changes its Z-order so that it

appears on top of all routes.

将 source hero 移至后台运行。

Moves the source hero offscreen.

hero 飞翔时,它的矩形边界使用 Hero 的

createRectTween 属性中特定的 Tween 进行动画。默认情况下,Flutter 使用 MaterialRectArcTween 的示例,它沿着一个曲线路径设置矩形对角动画。(参考 径向 hero 动画,该示例使用了不同的补间动画)

As the hero flies, its rectangular bounds are animated using

Tween, specified in Hero’s

createRectTween property.

By default, Flutter uses an instance of

MaterialRectArcTween, which animates the

rectangle’s opposing corners along a curved path.

(See Radial hero animations for an example

that uses a different Tween animation.)

当飞翔完成时:

When the flight completes:

Flutter 将 hero widget 从图层移动到目标页面。图层现在是空的。

Flutter moves the hero widget from the overlay to

the destination route. The overlay is now empty.

destination hero 出现在目标图层的最终位置。

The destination hero appears in its final position

in the destination route.

source hero 被储存到原页面中。

The source hero is restored to its route.

弹出的页面执行同样的过程,hero 动画回到原页面并回复原来大小和位置。

Popping the route performs the same process,

animating the hero back to its size

and location in the source route.

基本类

Essential classes

本指南中的示例使用了如下类来实现 hero 动画:

The examples in this guide use the following classes to

implement hero animations:

[Hero][]

:从原页面飞到目标页面的 widget。定义一个原页面的 Hero 和另一个目标页面的 Hero,并设置相同的标签。

Flutter 为成对的含有匹配标签的 heroes 设置动画。

Hero

The widget that flies from the source to the destination route.

Define one Hero for the source route and another for the

destination route, and assign each the same tag.

Flutter animates pairs of heroes with matching tags.

[Inkwell][]

指定点击 hero 时发生什么。

InkWell 的 onTap() 方法可以创建新页面并推送至 Navigator 的堆栈。

[Inkwell][]

Specifies what happens when tapping the hero.

The InkWell’s onTap() method builds the new route and pushes it

to the Navigator’s stack.

[Navigator][]

Navigator 管理一个页面堆栈。推送或弹出 Navigator 堆栈中的页面触发动画。

[Navigator][]

The Navigator manages a stack of routes. Pushing a route on or

popping a route from the Navigator’s stack triggers the animation.

Route

指定屏幕或页面。除最基本的应用程序外,大部分含有多页面。

[Route][]

Specifies a screen or page. Most apps, beyond the most basic,

have multiple routes.

标准 hero 动画

Standard hero animations

要点

What's the point?

使用 MaterialPageRoute,CupertinoPageRoute 指定页面,或使用 PageRouteBuilder 创建自定义页面。本章节示例使用的时 MaterialPageRoute。

Specify a route using MaterialPageRoute, CupertinoPageRoute, or

build a custom route using

PageRouteBuilder. The examples in this section use MaterialPageRoute.

在过渡的最后,通过在 SizedBox 中裹挟目标图像来改变图像大小。

Change the size of the image at the end of the transition by

wrapping the destination’s image in a SizedBox.

通过在布局 widget 中放置目标图像来改变图像位置。这些示例中使用 Container。

Change the location of the image by placing the destination’s

image in a layout widget. These examples use Container.

标准 hero 动画代码

Standard hero animation code

下面的每个示例都演示了一个图形从一页面飞至另一页面。本指南详细介绍第一个例子。

Each of the following examples demonstrates flying an image from one

route to another. This guide describes the first example.

hero_animation

将 hero 代码封装到自定义的 PhotoHero widget 中。沿 Material motion spec 中介绍的曲线路径设置 hero 动作的动画。

hero_animation

Encapsulates the hero code in a custom PhotoHero widget.

Animates the hero’s motion along a curved path,

as described in the Material motion spec.

basic_hero_animation

直接使用 hero widget。这个基础示例仅供参考,本指南中无详细介绍。

basic_hero_animation

Uses the hero widget directly.

This more basic example, provided for your reference, isn’t

described in this guide.

然后呢?

What’s going on?

使用 Flutter 的 hero widget 可以轻松实现图像由一个页面飞至另一个。当使用 MaterialPageRoute 指定新页面时,图像将沿 Material Design motion spec 中介绍的曲线路径飞翔。

Flying an image from one route to another is easy to implement

using Flutter’s hero widget. When using MaterialPageRoute

to specify the new route, the image flies along a curved path,

as described by the Material Design motion spec.

创建一个新的 Flutter 示例

和使用来自 [GitHub 仓库][GitHub directory.] 的文件更新。

Create a new Flutter example and

update it using the files from the

[GitHub directory.][]

运行示例:

To run the example:

点击主页的图片使图像飞至新页面并在不同位置以不同规格显示相同图片。

Tap on the home route’s photo to fly the image to a new route

showing the same photo at a different location and scale.

点击图像或使用设备的回到前页手势返回之前页面。

Return to the previous route by tapping the image, or by using the

device’s back-to-the-previous-route gesture.

可以使用 timeDilation 属性来减缓过渡。

You can slow the transition further using the timeDilation

property.

PhotoHero 类

PhotoHero class

自定义的 PhotoHero 类保留了 hero 以及其大小,图像,和点击时的动作。PhotoHero 创建如下 widget 树:

The custom PhotoHero class maintains the hero,

and its size, image, and behavior when tapped.

The PhotoHero builds the following widget tree:

代码如下:

Here’s the code:

class PhotoHero extends StatelessWidget {

const PhotoHero({ Key key, this.photo, this.onTap, this.width }) : super(key: key);

final String photo;

final VoidCallback onTap;

final double width;

Widget build(BuildContext context) {

return SizedBox(

width: width,

child: Hero(

tag: photo,

child: Material(

color: Colors.transparent,

child: InkWell(

onTap: onTap,

child: Image.asset(

photo,

fit: BoxFit.contain,

),

),

),

),

);

}

}

重要信息:

Key information:

当 HeroAnimation 作为应用程序的主页属性时,起始页面由 MaterialApp 隐式推送。

The starting route is implicitly pushed by MaterialApp when

HeroAnimation is provided as the app’s home property.

InkWell 裹挟图像,使得为 source hero 和

destination hero 添加点击动作变得简单。

An InkWell wraps the image, making it trivial to add a tap

gesture to the both the source and destination heroes.

用透明色定义 Material widget 使图片在飞至目标页时可以从背景中“弹出”。

Defining the Material widget with a transparent color

enables the image to “pop out” of the background as it

flies to its destination.

SizedBox 指定动画起始和结束时 hero 的大小。

The SizedBox specifies the hero’s size at the start and

end of the animation.

设置图像的 fit 属性到 BoxFit.contain,可以确保在过渡过程中尽可能放大,且不改变长宽比例。

Setting the Image’s fit property to BoxFit.contain,

ensures that the image is as large as possible during the

transition without changing its aspect ratio.

HeroAnimation 类

HeroAnimation class

HeroAnimation 类可以创建 source PhotoHero 和 destination PhotoHero,并建立过渡。

The HeroAnimation class creates the source and destination

PhotoHeroes, and sets up the transition.

代码如下:

Here’s the code:

class HeroAnimation extends StatelessWidget {

Widget build(BuildContext context) {

timeDilation = 5.0; // 1.0 means normal animation speed.

return Scaffold(

appBar: AppBar(

title: const Text('Basic Hero Animation'),

),

body: Center(

child: PhotoHero(

photo: 'images/flippers-alpha.png',

width: 300.0,

onTap: () {

Navigator.of(context).push(MaterialPageRoute(

builder: (BuildContext context) {

return Scaffold(

appBar: AppBar(

title: const Text('Flippers Page'),

),

body: Container(

// The blue background emphasizes that it's a new route.

color: Colors.lightBlueAccent,

padding: const EdgeInsets.all(16.0),

alignment: Alignment.topLeft,

child: PhotoHero(

photo: 'images/flippers-alpha.png',

width: 100.0,

onTap: () {

Navigator.of(context).pop();

},

),

),

);

}

));

},

),

),

);

}

}

重要信息:

Key information:

当用户点击含有 source hero 的 InkWell 时,代码使用 MaterialPageRoute

生成目标页面。并将目标页面推送至 Navigator 堆栈,触发动画。

When the user taps the InkWell containing the source hero,

the code creates the destination route using MaterialPageRoute.

Pushing the destination route to the Navigator’s stack triggers

the animation.

Container 将 PhotoHero 置于目标页面左上角,AppBar 的下方。

The Container positions the PhotoHero in the destination

route’s top-left corner, below the AppBar.

目标页 PhotoHero 的 onTap() 函数会弹出 Navigator 的堆栈,触发动画 Hero 飞回至原页面。

The onTap() method for the destination PhotoHero

pops the Navigator’s stack, triggering the animation

that flies the Hero back to the original route.

在调试时,可以使用 timeDilation 属性来减缓过渡。

Use the timeDilation property to slow the transition

while debugging.

径向 hero 动画

Radial hero animations

要点

What's the point?

径向过渡 是由圆形变成正方形的过渡动画。

A radial transformation animates a circular shape into a square

shape.

径向 hero 动画在 hero 从原页面飞至目标页面时,执行径向过渡。

A radial hero animation performs a radial transformation while

flying the hero from the source route to the destination route.

MaterialRectCenter­Arc­Tween 定义了补间动画。

MaterialRectCenter­Arc­Tween defines the tween animation.

使用 PageRouteBuilder 创建目标页。

Build the destination route using PageRouteBuilder.

hero 从一个页面飞至另一页的同时由圆形过渡到矩形,这是一个滑入效果,可使用 Hero widgets 来实现。要做到这一点,代码需要动画两个剪裁形状的交叉:一个圆形和一个正方形。整个动画中,圆形剪裁(和图片)由

minRadius 缩放到 maxRadius,而正方形剪裁保持大小不变。同时,图像从原页面飞至目标页面的相同位置。这个过渡的效果示例,请参见 Material motion spec 中的 Radial transformation。

Flying a hero from one route to another as it transforms

from a circular shape to a rectangular shape is a slick

effect that you can implement using Hero widgets.

To accomplish this, the code animates the intersection of

two clip shapes: a circle and a square.

Throughout the animation, the circle clip (and the image)

scales from minRadius to maxRadius, while the square

clip maintains constant size. At the same time,

the image flies from its position in the source route to its

position in the destination route. For visual examples

of this transition, see Radial transformation

in the Material motion spec.

这个动画看起来复杂,但是您可以根据自身需要自定义范例。艰巨的工作已为您完成。

This animation might seem complex (and it is), but you can customize the

provided example to your needs. The heavy lifting is done for you.

径向 hero 动画代码

Radial hero animation code

下面的每个示例都演示了一个径向 hero 动画。本指南详细介绍第一个示例。

Each of the following examples demonstrates a radial hero animation.

This guide describes the first example.

radial_hero_animation

Material motion spec 中详细介绍了这个径向 hero 动画。

radial_hero_animation

A radial hero animation as described in the Material motion spec.

basic_radial_hero_animation

径向 hero 动画最简单的示例。目标页面没有 Scaffold, Card, Column, 或 Text。这个基本示例仅供参考,本指南不详述。

basic_radial_hero_animation

The simplest example of a radial hero animation. The destination

route has no Scaffold, Card, Column, or Text.

This basic example, provided for your reference, isn’t

described in this guide.

radial_hero_animation_animate_rectclip

通过动画矩形剪裁大小,扩展径向 hero 动画。这个高阶示例亦供参考,本指南不详述。

radial_hero_animation_animate_rectclip

Extends radial_hero_animaton by also animating the size of the

rectangular clip. This more advanced example,

provided for your reference, isn’t described in this guide.

技巧:

Pro tip:

径向 hero 动画设计圆形和正方形的交叉。这个很难看出来,即使使用 timeDilation 来减慢动画。所以在开发时,可以考虑启用 Flutter 的 debugPaintSizeEnabled 这个 flag。

The radial hero animation involves intersecting a round shape with

a square shape. This can be hard to see, even when slowing

the animation with timeDilation, so you might consider enabling

the debugPaintSizeEnabled flag during development.

然后呢?

What’s going on?

下面的图表显示了在动画起始(t = 0.0)和结束(t = 1.0)时的剪裁图像。

The following diagram shows the clipped image at the beginning

(t = 0.0), and the end (t = 1.0) of the animation.

蓝色渐变(代表图像),表明剪裁形状交叉的位置。在过渡的开始,交叉的结果是圆形剪裁

([ClipOval][])。在过渡过程中,ClipOval 由 minRadius 缩放至 maxRadius,

ClipRect 则保持原尺寸。

The blue gradient (representing the image), indicates where the clip

shapes intersect. At the beginning of the transition,

the result of the intersection is a circular clip

([ClipOval][]).

During the transformation,

the ClipOval scales from minRadius to maxRadius while the

ClipRect

maintains a constant size.

在过渡结束时,圆形和矩形剪裁的交集产生一个与 hero widget 相同大小的矩形。也就是说,在过渡结束时,图片已不再被剪裁。

At the end of the transition the intersection of the circular and

rectangular clips yield a rectangle that’s the same size as the hero

widget. In other words, at the end of the transition the image is no

longer clipped.

Create a new Flutter example and

update it using the files from the

radial_hero_animation GitHub directory.

运行示例:

To run the example:

点击三个圆形缩略图中的任意一个,使图像变成位于新页面中间的一个较大的正方形,且覆盖原页面。

Tap on one of the three circular thumbnails to animate the image

to a larger square positioned in the middle of a new route that

obscures the original route.

点击图片或使用设备的返回手势,返回之前页面。

Return to the previous route by tapping the image, or by using the

device’s back-to-the-previous-route gesture.

可以使用 timeDilation 属性来减缓过渡。

You can slow the transition further using the timeDilation

property.

Photo 类

Photo class

Photo 类创建保存图像的 widget 树:

The Photo class builds the widget tree that holds the image:

class Photo extends StatelessWidget {

Photo({ Key key, this.photo, this.color, this.onTap }) : super(key: key);

final String photo;

final Color color;

final VoidCallback onTap;

Widget build(BuildContext context) {

return Material(

// Slightly opaque color appears where the image has transparency.

color: Theme.of(context).primaryColor.withOpacity(0.25),

child: InkWell(

onTap: onTap,

child: Image.asset(

photo,

fit: BoxFit.contain,

)

),

);

}

}

重要信息:

Key information:

Inkwell 捕捉点击动作。调用函数将 onTap() 函数传递给 Photo 的构造函数。

The Inkwell captures the tap gesture.

The calling function passes the onTap() function to the

Photo’s constructor.

飞翔过程中,InkWell 的飞溅效果会出现在它第一个 Material 祖先上。

During flight, the InkWell draws its splash on its

first Material ancestor.

Material widget 有轻微不透明色,所以图像的透明部分会被渲染上颜色。这确保了圆形到正方形过渡,即使是透明的图像依然清晰可见。

The Material widget has a slightly opaque color, so the

transparent portions of the image are rendered with color.

This ensures that the circle-to-square transition is easy to see,

even for images with transparency.

Photo 类的 widget 树中并不包含 Hero。为了使动画运行,hero需要包裹 RadialExpansion widget。

The Photo class does not include the Hero in its widget tree.

For the animation to work, the hero

wraps the RadialExpansion widget.

RadialExpansion 类

RadialExpansion class

RadialExpansion widget,demo 的核心,建立过渡过程中剪裁图像的 widget 树。剪裁的形状来自于圆形剪裁(飞翔过程中增长)和矩形剪裁(自始至终保持一致大小)的交集。

The RadialExpansion widget, the core of the demo, builds the

widget tree that clips the image during the transition.

The clipped shape results from the intersection of a circular clip

(that grows during flight),

with a rectangular clip (that remains a constant size throughout).

为此,它建立了如下 widget 树:

To do this, it builds the following widget tree:

代码如下:

Here’s the code:

class RadialExpansion extends StatelessWidget {

RadialExpansion({

Key key,

this.maxRadius,

this.child,

}) : clipRectSize = 2.0 * (maxRadius / math.sqrt2),

super(key: key);

final double maxRadius;

final clipRectSize;

final Widget child;

@override

Widget build(BuildContext context) {

return ClipOval(

child: Center(

child: SizedBox(

width: clipRectSize,

height: clipRectSize,

child: ClipRect(

child: child, // Photo

),

),

),

);

}

}

重要信息:

Key information:

hero 包裹 RadialExpansion widget。

The hero wraps the RadialExpansion widget.

hero 飞翔时会改变大小,因为它限制了 child 的大小,所以 RadialExpansion widget 会改变大小以匹配。

As the hero flies, its size changes and,

because it constrains its child’s size,

the RadialExpansion widget changes size to match.

RadialExpansion 动画由两个重叠的剪裁创建。

The RadialExpansion animation is created by two overlapping clips.

这个示例用 MaterialRectCenterArcTween 定义了补间插值。

hero 动画的默认飞翔路径,利用 heroes 的角插值补间。这个方法会影响到径向过渡时 hero 的长宽比例,所以新的飞翔路径使用 MaterialRectCenterArcTween 方法,利用每个 hero 的中心点来插值补间。

The example defines the tweening interpolation using

MaterialRectCenterArcTween.

The default flight path for a hero animation

interpolates the tweens using the corners of the heroes.

This approach affects the hero’s aspect ratio during

the radial transformation, so the new flight path uses

MaterialRectCenterArcTween to interpolate the tweens using the

center point of each hero.

代码如下:

Here’s the code:

static RectTween _createRectTween(Rect begin, Rect end) {

return MaterialRectCenterArcTween(begin: begin, end: end);

}

The hero’s flight path still follows an arc,

but the image’s aspect ratio remains constant.

参考资料

Resources

下面的参考资料对编写动画会有帮助:

The following resources might help when writing animations:

Lists the available documentation for Flutter animations.

If tweens are new to you, check out the

Animations tutorial.

现有的一些 Flutter 动画文档。如果您还不了解 tween,可以参考这里 Animations tutorial

Reference documentation for all of the Flutter libraries.

In particular, see the animation

library

documentation.

Flutter 库所有的参考文档。特别是 animation

library 文档。

Demo app showcasing many Material Design widgets and other Flutter

features. The Shrine

demo

implements a hero animation.

Demo 应用程序展示了许多 Material Design widgets 和其他 Flutter 特征。Shrine

demo

执行了一个 hero 动画。

Describes motion for Material design apps.

介绍使用 Material 设计应用程序的动作。

android hero动画,主动画 (Hero animations)相关推荐

  1. 【Flutter】Hero 动画 ( Hero 动画使用流程 | 创建 Hero 动画核心组件 | 创建源页面 | 创建目的页面 | 页面跳转 )

    文章目录 ◯.Hero 动画简介 一.创建 Hero 动画核心组件 二.创建源页面 三.创建目的页面 四.页面跳转 五.完整代码示例 六.相关资源 ◯.Hero 动画简介 Hero Widget 动画 ...

  2. 31、Flutter之Hero动画

    Flutter Hero动画 Hero指的是可以在路由(页面)之间"飞行"的widget. 使用Flutter的Hero widget创建hero动画. 将 hero从一个路由飞到 ...

  3. 【Flutter】Hero 动画 ( Hero 实现径向动画 | Hero 组件 createRectTween 设置 )

    文章目录 ◯.Hero 构造函数 一.圆形方形组件 二.创建页面 1 的组件 ( Hero 组件 1 ) 三.创建页面 2 的组件 ( Hero 组件 2 ) 四.完整代码示例 五.相关资源 ◯.He ...

  4. Flutter(十六)——Hero动画

    本文目录 前言 基本用法 实现原理 前言 在前面实践组件的开发中,我们做了一个登录的界面,里面有一个组件Hero,不知道大家是否记得?当时没有展开来说,是因为它属于动画的内容,本文就要重点讲解Hero ...

  5. vue 页面切换动画_Flutter Hero动画让你的APP页面切换充满动效 不一样的体验 不一样的细节处理...

    优美的应用体验 来自于细节的处理,更源自于码农的自我要求与努力,当然也需要码农年轻灵活的思维. 本文章实现的Demo效果,如下图所示: class HeroHomePage extends State ...

  6. Flutter Hero动画让你的APP页面切换充满动效 不一样的体验 不一样的细节处理

    优美的应用体验 来自于细节的处理,更源自于码农的自我要求与努力,当然也需要码农年轻灵活的思维. 本文章实现的Demo效果,如下图所示: 1 首先是页面的主体 在这里使用的是Scaffold脚手架来构建 ...

  7. Flutter动画 4 - Hero动画

    概述 花瓣App的转场动画,这么多年还是没变,还是图片转场动画. 网上有很多人实现过相关效果,先前骚栋18年在做iOS项目的时候,也实现的类似的效果,但是全程实现起来还是比较麻烦,需要自己来定义转场动 ...

  8. SwiftUI中应用Hero动画(Hero Animation)时一些需要填的坑

    功能需求 从SwiftUI 2.0开始(iOS 14.0),Apple提供了视图间更自然的变换动画,我们可以据此来实现所谓的Hero Animation,即"英雄动画"效果: 注意 ...

  9. flutter 九宫格菜单_Flutter 九宫格及Hero动画

    class LXPhotosView extends StatefulWidget { //数据资源 final List list; //主轴间距 final double mainAxisPadd ...

最新文章

  1. 是男人就过8题!楼教主出题,请接招!
  2. 对输入框进行探索性测试思路
  3. 新手站长们如何利用10分钟的时间内多写高质量的原创量?
  4. LeetCode Reverse String(字符串反转)
  5. 现在的位置就是对的啊,意思就是当鼠标放上去的时候,停止滚动,鼠标离开,继续滚动(跑马灯项目功能)...
  6. php版 v2.0,KangPHP v2.0 正式版
  7. Java NIO教程
  8. jstl c:choose、c:when和c:otherwise标签的简单使用介绍
  9. PHP:函数赋参数默认初值
  10. 卸载python会删除pip安装的包吗_python 使用pip安装,卸载,升级和查看包
  11. PyCharm入门教程——多个插入符号
  12. 【软件设计】BDD由内而外采用策略
  13. 知识付费网站源码可开分站一键更新后台数据
  14. Linux 网络编程: daytime Service
  15. 旧版本CUDA下载路径
  16. python 利用python处理excel文件
  17. IDEA插件:多线程文件下载插件开发
  18. html页面和手机比例一致 一比一自适应 Mixed Content: The page at ‘xxx‘ was loaded over HTTPS, but requested an insec
  19. c语言expand函数,编撰expand(s1,s2)
  20. PAT乙级真题1058 || 选择题(详解,C/C++示例,测试点分析)

热门文章

  1. android asyc异步获取网络图片为bitmap,异步之AsyncTask(一)
  2. 3G移动网络,给WAP带来什么?
  3. 【043】RainyMood-下雨天的粉红噪音
  4. 模拟火车站售票窗口,开启三个窗口售票,总票数为100张
  5. web前端学习笔记(二)
  6. 传感器实验——寻迹模块
  7. 走出软件作坊之十七-走钢索的人
  8. JVM垃圾收集—垃圾收集器及常见组合参数
  9. 早期RA获超声缓解的基线预测因素
  10. “联通云”正式浮出水面 要讲出云计算怎样的“新故事”?