android hero动画,主动画 (Hero animations)
主动画 (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.
MaterialRectCenterArcTween 定义了补间动画。
MaterialRectCenterArcTween 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)相关推荐
- 【Flutter】Hero 动画 ( Hero 动画使用流程 | 创建 Hero 动画核心组件 | 创建源页面 | 创建目的页面 | 页面跳转 )
文章目录 ◯.Hero 动画简介 一.创建 Hero 动画核心组件 二.创建源页面 三.创建目的页面 四.页面跳转 五.完整代码示例 六.相关资源 ◯.Hero 动画简介 Hero Widget 动画 ...
- 31、Flutter之Hero动画
Flutter Hero动画 Hero指的是可以在路由(页面)之间"飞行"的widget. 使用Flutter的Hero widget创建hero动画. 将 hero从一个路由飞到 ...
- 【Flutter】Hero 动画 ( Hero 实现径向动画 | Hero 组件 createRectTween 设置 )
文章目录 ◯.Hero 构造函数 一.圆形方形组件 二.创建页面 1 的组件 ( Hero 组件 1 ) 三.创建页面 2 的组件 ( Hero 组件 2 ) 四.完整代码示例 五.相关资源 ◯.He ...
- Flutter(十六)——Hero动画
本文目录 前言 基本用法 实现原理 前言 在前面实践组件的开发中,我们做了一个登录的界面,里面有一个组件Hero,不知道大家是否记得?当时没有展开来说,是因为它属于动画的内容,本文就要重点讲解Hero ...
- vue 页面切换动画_Flutter Hero动画让你的APP页面切换充满动效 不一样的体验 不一样的细节处理...
优美的应用体验 来自于细节的处理,更源自于码农的自我要求与努力,当然也需要码农年轻灵活的思维. 本文章实现的Demo效果,如下图所示: class HeroHomePage extends State ...
- Flutter Hero动画让你的APP页面切换充满动效 不一样的体验 不一样的细节处理
优美的应用体验 来自于细节的处理,更源自于码农的自我要求与努力,当然也需要码农年轻灵活的思维. 本文章实现的Demo效果,如下图所示: 1 首先是页面的主体 在这里使用的是Scaffold脚手架来构建 ...
- Flutter动画 4 - Hero动画
概述 花瓣App的转场动画,这么多年还是没变,还是图片转场动画. 网上有很多人实现过相关效果,先前骚栋18年在做iOS项目的时候,也实现的类似的效果,但是全程实现起来还是比较麻烦,需要自己来定义转场动 ...
- SwiftUI中应用Hero动画(Hero Animation)时一些需要填的坑
功能需求 从SwiftUI 2.0开始(iOS 14.0),Apple提供了视图间更自然的变换动画,我们可以据此来实现所谓的Hero Animation,即"英雄动画"效果: 注意 ...
- flutter 九宫格菜单_Flutter 九宫格及Hero动画
class LXPhotosView extends StatefulWidget { //数据资源 final List list; //主轴间距 final double mainAxisPadd ...
最新文章
- 是男人就过8题!楼教主出题,请接招!
- 对输入框进行探索性测试思路
- 新手站长们如何利用10分钟的时间内多写高质量的原创量?
- LeetCode Reverse String(字符串反转)
- 现在的位置就是对的啊,意思就是当鼠标放上去的时候,停止滚动,鼠标离开,继续滚动(跑马灯项目功能)...
- php版 v2.0,KangPHP v2.0 正式版
- Java NIO教程
- jstl c:choose、c:when和c:otherwise标签的简单使用介绍
- PHP:函数赋参数默认初值
- 卸载python会删除pip安装的包吗_python 使用pip安装,卸载,升级和查看包
- PyCharm入门教程——多个插入符号
- 【软件设计】BDD由内而外采用策略
- 知识付费网站源码可开分站一键更新后台数据
- Linux 网络编程: daytime Service
- 旧版本CUDA下载路径
- python 利用python处理excel文件
- IDEA插件:多线程文件下载插件开发
- html页面和手机比例一致 一比一自适应 Mixed Content: The page at ‘xxx‘ was loaded over HTTPS, but requested an insec
- c语言expand函数,编撰expand(s1,s2)
- PAT乙级真题1058 || 选择题(详解,C/C++示例,测试点分析)