在屏幕之间动画一个 widget
在用户从一个屏幕导航到另一个屏幕时,引导他们使用应用程序通常很有帮助。引导用户使用应用程序的常见技术是将小部件从一个屏幕动画化到下一个屏幕。这会创建一个连接两个屏幕的视觉锚点。
使用 Hero
小部件将小部件从一个屏幕动画化到下一个屏幕。本食谱使用以下步骤:
- 创建两个显示相同图片的屏幕。
- 将
Hero
小部件添加到第一个屏幕。 - 将
Hero
小部件添加到第二个屏幕。
1. 创建两个显示相同图片的屏幕
#在此示例中,在两个屏幕上显示相同的图片。当用户点击图片时,将图片从第一个屏幕动画化到第二个屏幕。目前,先创建视觉结构;动画将在后续步骤中处理。
dart
import 'package:flutter/material.dart';
class MainScreen extends StatelessWidget {
const MainScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Main Screen')),
body: GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return const DetailScreen();
},
),
);
},
child: Image.network('https://picsum.photos/250?image=9'),
),
);
}
}
class DetailScreen extends StatelessWidget {
const DetailScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: Center(
child: Image.network('https://picsum.photos/250?image=9'),
),
),
);
}
}
2. 将 Hero
小部件添加到第一个屏幕
#为了通过动画将两个屏幕连接在一起,请将两个屏幕上的 Image
小部件包装在 Hero
小部件中。Hero
小部件需要两个参数:
tag
- 一个用于识别
Hero
的对象。它在两个屏幕上必须相同。 child
- 要在屏幕之间动画化的小部件。
dart
Hero(
tag: 'imageHero',
child: Image.network('https://picsum.photos/250?image=9'),
)
3. 将 Hero
小部件添加到第二个屏幕
#为了完成与第一个屏幕的连接,请将第二个屏幕上的 Image
包装在一个 Hero
小部件中,该小部件的 tag
必须与第一个屏幕中的 Hero
相同。
将 Hero
小部件应用于第二个屏幕后,屏幕之间的动画将自动生效。
dart
Hero(
tag: 'imageHero',
child: Image.network('https://picsum.photos/250?image=9'),
)
互动示例
#import 'package:flutter/material.dart';
void main() => runApp(const HeroApp());
class HeroApp extends StatelessWidget {
const HeroApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(title: 'Transition Demo', home: MainScreen());
}
}
class MainScreen extends StatelessWidget {
const MainScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Main Screen')),
body: GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return const DetailScreen();
},
),
);
},
child: Hero(
tag: 'imageHero',
child: Image.network('https://picsum.photos/250?image=9'),
),
),
);
}
}
class DetailScreen extends StatelessWidget {
const DetailScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: Center(
child: Hero(
tag: 'imageHero',
child: Image.network('https://picsum.photos/250?image=9'),
),
),
),
);
}
}