返回介绍

Animating a Widget across screens

发布于 2019-12-09 21:31:30 字数 5371 浏览 926 评论 0 收藏 0

It’s often helpful to guide users through our apps as they navigate from screen to screen. A common technique to lead users through an app is to animate a Widget from one screen to the next. This creates a visual anchor connecting the two screens.

How can we animate a Widget from one screen to the next with Flutter? Using the Hero Widget!

Directions

  1. Create two screens showing the same image
  2. Add a Hero Widget to the first screen
  3. Add a Hero Widget to the second screen

1. Create two screens showing the same image

In this example, we’ll display the same image on both screens. We’ll want to animate the image from the first screen to the second screen when the user taps on the image. For now, we’ll create the visual structure, and handle animations in the next steps!

Note: This example builds upon the Navigate to a new screen and back and Handling Taps recipes.

class MainScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Main Screen'),
      ),
      body: GestureDetector(
        onTap: () {
          Navigator.push(context, MaterialPageRoute(builder: (_) {
            return DetailScreen();
          }));
        },
        child: Image.network(
          'https://picsum.photos/250?image=9',
        ),
      ),
    );
  }
}

class DetailScreen extends StatelessWidget {
  @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. Add a Hero Widget to the first screen

In order to connect the two screens together with an animation, we need to wrap the Image Widget on both screens in a Hero Widget. The Hero Widget requires two arguments:

  1. tag: An object that identifies the Hero. It must be the same on both screens.
  2. child: The Widget we want to animate across screens.
Hero(
  tag: 'imageHero',
  child: Image.network(
    'https://picsum.photos/250?image=9',
  ),
);

3. Add a Hero Widget to the second screen

To complete the connection with the first screen, we need to wrap the Image on the second screen with a Hero Widget as well! It must use the same tag as the first screen.

After you apply the Hero Widget to the second screen, the animation between screens will work!

Hero(
  tag: 'imageHero',
  child: Image.network(
    'https://picsum.photos/250?image=9',
  ),
);

Note: this code is identical to what we had on the first screen! In general, you could create a reusable Widget instead of repeating code, but for this example, we’ll duplicate the code for demonstration purposes.

Complete example

import 'package:flutter/material.dart';

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

class HeroApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Transition Demo',
      home: MainScreen(),
    );
  }
}

class MainScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Main Screen'),
      ),
      body: GestureDetector(
        child: Hero(
          tag: 'imageHero',
          child: Image.network(
            'https://picsum.photos/250?image=9',
          ),
        ),
        onTap: () {
          Navigator.push(context, MaterialPageRoute(builder: (_) {
            return DetailScreen();
          }));
        },
      ),
    );
  }
}

class DetailScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: GestureDetector(
        child: Center(
          child: Hero(
            tag: 'imageHero',
            child: Image.network(
              'https://picsum.photos/250?image=9',
            ),
          ),
        ),
        onTap: () {
          Navigator.pop(context);
        },
      ),
    );
  }
}

Hero Demo

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文