让你的切换丝滑起来,Hero animations的介绍
Hero动画是什么
在页面跳转过程中给用户加以引导是非常有用的。实现引导的一种通用做法是在页面切换时为某个组件加上转场动画,从而在两个页面间建立视觉上的锚定关联。
标准Hero动画如何实现
标准Hero动画的实现涉及两个主要步骤:
-
定义Hero元素:在需要动画效果的两个页面上定义具有相同tag的Hero元素。这个tag可以是任意的字符串,但在两个页面中必须一致。
-
页面过渡动画:在页面导航时,Flutter会自动识别具有相同tag的Hero元素,并生成平滑的过渡动画。
以下是一个简单的示例:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Hero Animation Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: FirstPage(),
);
}
}
class FirstPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('First Page'),
),
body: Center(
child: GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondPage()),
);
},
child: Hero(
tag: 'hero-tag',
child: Icon(
Icons.star,
size: 50.0,
),
),
),
),
);
}
}
class SecondPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Second Page'),
),
body: Center(
child: Hero(
tag: 'hero-tag',
child: Icon(
Icons.star,
size: 150.0,
),
),
),
);
}
}
在这个示例中,我们在两个页面上定义了具有相同tag
的Hero元素。当用户点击第一个页面上的星形图标时,Flutter会自动生成平滑的过渡动画,将图标从一个页面“飞”到另一个页面。
Hero的函数原型是什么
在Flutter中,Hero
类的构造函数原型如下:
Hero({
Key? key,
required Object tag,
required Widget child,
CreateRectTween? createRectTween,
HeroFlightShuttleBuilder? flightShuttleBuilder,
HeroPlaceholderBuilder? placeholderBuilder,
bool transitionOnUserGestures = false,
})
key
:Hero元素的唯一标识符。tag
:用来匹配两个页面之间Hero元素的标记。child
:Hero元素的子Widget。createRectTween
:自定义矩形动画的函数。flightShuttleBuilder
:自定义飞行期间的Widget。placeholderBuilder
:自定义占位符的Widget。transitionOnUserGestures
:是否在用户手势操作时触发过渡动画。
径向Hero动画实现
径向Hero动画是一种特殊的Hero动画,它将Hero元素的过渡路径定义为径向路径。为了实现这种效果,我们需要自定义RectTween
。
首先,我们需要一个自定义的RectTween
类:
class CircularRectTween extends RectTween {
CircularRectTween({required Rect begin, required Rect end}) : super(begin: begin, end: end);
@override
Rect lerp(double t) {
double centerX = lerpDouble(begin!.center.dx, end!.center.dx, t)!;
double centerY = lerpDouble(begin!.center.dy, end!.center.dy, t)!;
double width = lerpDouble(begin!.width, end!.width, t)!;
double height = lerpDouble(begin!.height, end!.height, t)!;
return Rect.fromCenter(center: Offset(centerX, centerY), width: width, height: height);
}
}
接下来,我们在Hero中使用这个自定义的RectTween
:
class FirstPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('First Page'),
),
body: Center(
child: GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondPage()),
);
},
child: Hero(
tag: 'hero-tag',
createRectTween: (begin, end) {
return CircularRectTween(begin: begin!, end: end!);
},
child: Icon(
Icons.star,
size: 50.0,
),
),
),
),
);
}
}
class SecondPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Second Page'),
),
body: Center(
child: Hero(
tag: 'hero-tag',
child: Icon(
Icons.star,
size: 150.0,
),
),
),
);
}
}
通过自定义RectTween
,我们可以实现径向Hero动画,使过渡路径看起来更加自然和圆滑。
结语
Hero动画不仅可以增强用户体验,还能让应用程序看起来更具吸引力和互动性。无论是标准Hero动画还是自定义径向Hero动画,Flutter都提供了强大的工具和灵活的接口,让我们能够轻松实现各种酷炫的动画效果。希望这篇博客能帮助你更好地理解和实现Hero动画。
转载自:https://juejin.cn/post/7386936832608993291