Flutter之Hero动画

914 阅读2分钟

前言

Hero动画是Flutter中的一种过渡动画,它允许在页面之间共享同一个元素,并在页面之间平滑地过渡它们的大小、位置、以及外观。通常,Hero动画在页面路由过渡(例如从一个页面切换到另一个页面)时使用,以提供一种流畅、连续的用户体验。

20200203143611964.gif

内容

Hero动画的基本原理是,在两个页面之间共享相同的标签(通常是一个具有相同tag属性的小部件)。当用户触发页面切换时,原始页面上的Hero小部件会从其当前位置平滑过渡到目标页面上对应Hero小部件的位置,同时进行透明度、大小、形状等属性的变换。

以下是实现Hero动画的基本步骤:

  1. 在原始页面和目标页面上分别放置相同tag属性的Hero小部件,它们应该是具有相同外观的小部件(例如,可以是图片、图标等)。
  2. 使用Navigator的pushpushReplacement方法从原始页面导航到目标页面。
  3. 目标页面上的Hero小部件应该与原始页面上的Hero小部件拥有相同的tag属性,这样Flutter就能够识别它们并进行过渡动画。
  4. 在目标页面上,使用Hero小部件包装目标Hero,指定tag属性,并将其用于实际显示的小部件,以便执行过渡动画。
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      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: (_) => SecondPage()));
          },
          child: Hero(
            tag: 'imageTag',
            child: Image.asset('assets/image.jpg', width: 100, height: 100),
          ),
        ),
      ),
    );
  }
}

class SecondPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Second Page'),
      ),
      body: Center(
        child: GestureDetector(
          onTap: () {
            Navigator.pop(context);
          },
          child: Hero(
            tag: 'imageTag',
            child: Image.asset('assets/image.jpg', width: 200, height: 200),
          ),
        ),
      ),
    );
  }
}

在上述示例中,在第一个页面和第二个页面上都使用了相同tag属性的Hero小部件,这样它们就能够相互匹配并进行过渡动画。当用户在第一个页面上点击图片时,导航到第二个页面,Hero动画会平滑地将图片从第一个页面的位置过渡到第二个页面的位置,并在过渡期间调整图片的大小。

通过使用Hero动画,可以为应用添加更加流畅和吸引人的页面过渡效果,提升用户体验。请注意,由于Hero动画需要在两个页面上共享相同的tag,因此在页面切换时确保两个页面上的tag属性是唯一的是很重要的。