在屏幕之间动画一个 widget
在用户从一个屏幕导航到另一个屏幕时,引导他们完成应用通常很有帮助。连接用户浏览应用的常用技术是在一个屏幕到下一个屏幕之间动画化 Widget。这会创建一个连接两个屏幕的视觉锚点。
使用 Hero
Widget 将 Widget 从一个屏幕动画到下一个屏幕。本指南使用以下步骤:
- 创建两个显示相同图像的屏幕。
- 在第一个屏幕上添加
Hero
Widget。 - 在第二个屏幕上添加
Hero
Widget。
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<void>(
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
Widget
#要通过动画连接两个屏幕,请将两个屏幕上的 Image
Widget 包装在 Hero
Widget 中。Hero
Widget 需要两个参数:
tag
- 一个标识
Hero
的对象。它在两个屏幕上必须相同。 child
- 要在屏幕之间动画的 Widget。
dart
Hero(
tag: 'imageHero',
child: Image.network('https://picsum.photos/250?image=9'),
)
3. 在第二个屏幕上添加 Hero
Widget
#为了完成与第一个屏幕的连接,请将第二个屏幕上的 Image
包装在 Hero
Widget 中,该 Widget 具有与第一个屏幕中的 Hero
相同的 tag
。
在将 Hero
Widget 应用于第二个屏幕后,屏幕之间的动画就会自动生效。
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<void>(
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'),
),
),
),
);
}
}