Flutter页面过渡动画插件hero_animation的使用
Flutter页面过渡动画插件 hero_animation
的使用
HeroAnimation
是一个用于在同一个路由内实现页面过渡动画的Flutter插件。它允许你将一个子组件从一个布局位置平滑地移动到另一个位置,并且可以在可滚动视图中工作。
如何工作?
你可以通过以下资源了解其具体工作原理:
使用方法
当两个帧之间,具有相同标签的 HeroAnimation
组件的位置发生变化时,就会触发英雄动画。使用 key
来让Flutter框架检测到同一树节点下的 HeroAnimation
重新定位。
HeroAnimationScene
提供了飞行配置给底层的英雄,这些英雄必须是 HeroAnimation
小部件的祖先。
示例代码:在同一棵树节点下重新定位
import 'package:flutter/material.dart';
import 'package:hero_animation/hero_animation.dart';
class RepositioningExample extends StatefulWidget {
@override
_RepositioningExampleState createState() => _RepositioningExampleState();
}
class _RepositioningExampleState extends State<RepositioningExample> {
Alignment alignment = Alignment.centerLeft;
@override
Widget build(BuildContext context) {
return HeroAnimationScene(
duration: const Duration(milliseconds: 500),
curve: Curves.easeIn,
child: GestureDetector(
onTap: () {
setState(() {
alignment = Alignment.centerRight;
});
},
child: Align(
alignment: alignment,
child: HeroAnimation.child(
tag: 'tag_0',
child: const Text('SOME TEXT'),
),
),
),
);
}
}
在不同树节点间重新定位
HeroAnimation
允许根据 FlightState
重建其子组件。
import 'package:flutter/material.dart';
import 'package:hero_animation/hero_animation.dart';
enum Item { item1, item2, item3 }
extension ItemExtension on Item {
String getTitle(bool firstFlightEnded) {
return firstFlightEnded ? "Landed $name" : name;
}
}
class DifferentTreeNodeExample extends StatefulWidget {
@override
_DifferentTreeNodeExampleState createState() => _DifferentTreeNodeExampleState();
}
class _DifferentTreeNodeExampleState extends State<DifferentTreeNodeExample> {
List<Item> _landedItems = [];
int _itemPointer = 0;
Item _currentItem = Item.item1;
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
..._landedItems.map((item) => HeroAnimation.builder(
tag: item.name,
builder: (context, flightState, child) {
final firstFlightEnded = flightState.firstFlightEnded();
return AnimatedSwitcher(
child: Container(
alignment: Alignment.centerLeft,
key: ValueKey(firstFlightEnded),
child: Text(item.getTitle(firstFlightEnded)),
),
);
},
)),
ElevatedButton(
onPressed: () {
setState(() {
_landedItems.add(_currentItem);
_itemPointer++;
_currentItem = Item.values[_itemPointer];
});
},
child: Text('Add Item'),
)
],
);
}
}
完整示例 Demo
以下是完整的示例代码,展示了如何在实际应用中使用 HeroAnimation
插件:
import 'package:flutter/material.dart';
import 'package:hero_animation/hero_animation.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: DefaultTabController(
length: 2,
child: Scaffold(
appBar: AppBar(
title: TabBar(
tabs: <Widget>[
Tab(text: 'Flight state usage'),
Tab(text: 'Cup Game'),
],
),
),
body: TabBarView(
children: <Widget>[
FlightStateDemoPage(),
CupGamePage(),
],
),
),
),
);
}
}
// 这里省略了具体的页面实现细节,例如 FlightStateDemoPage 和 CupGamePage。
// 请参考上面的例子来实现这两个页面。
以上代码展示了如何在一个简单的Flutter应用程序中集成 HeroAnimation
插件,并演示了两种不同的使用场景:在同一棵树节点下重新定位和在不同树节点间重新定位。
更多关于Flutter页面过渡动画插件hero_animation的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter页面过渡动画插件hero_animation的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何在Flutter中使用hero_animation
插件来实现页面过渡动画的示例代码。不过需要注意的是,实际上Flutter本身已经内置了Hero动画功能,无需额外安装hero_animation
插件。因此,以下示例将直接使用Flutter内置的Hero动画功能。
示例代码
1. 创建主页面(MainPage)
import 'package:flutter/material.dart';
class MainPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Main Page'),
),
body: Center(
child: Hero(
tag: 'heroTag',
child: Material(
color: Colors.blue,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
),
child: InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => DetailPage()),
);
},
child: Container(
width: 100,
height: 100,
child: Center(child: Text('Go to Detail')),
),
),
),
),
),
);
}
}
2. 创建详情页面(DetailPage)
import 'package:flutter/material.dart';
class DetailPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Detail Page'),
),
body: Center(
child: Hero(
tag: 'heroTag',
child: Material(
color: Colors.blue,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
),
child: Container(
width: 200,
height: 200,
child: Center(child: Text('Detail Page')),
),
),
),
),
);
}
}
3. 主程序入口(main.dart)
import 'package:flutter/material.dart';
import 'main_page.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MainPage(),
);
}
}
解释
-
MainPage:在
MainPage
中,我们创建了一个带有Hero
动画的按钮。Hero
的tag
属性用于在两个页面之间识别相同的动画对象。当点击按钮时,会导航到DetailPage
。 -
DetailPage:在
DetailPage
中,我们也创建了一个Hero
对象,并且使用与MainPage
中相同的tag
。这样,当从MainPage
导航到DetailPage
时,Flutter会自动在两个页面之间应用过渡动画。 -
main.dart:主程序入口,设置了应用程序的主题和初始页面为
MainPage
。
运行效果
当你运行这个应用程序并点击MainPage
中的按钮时,你会看到一个带有过渡动画的蓝色方块从MainPage
移动到DetailPage
,并且在DetailPage
中变大。
这个示例展示了如何在Flutter中使用内置的Hero动画功能来实现页面之间的过渡动画,而无需额外的hero_animation
插件。