跳至主要內容

在畫面之間為元件加上動畫效果

引導使用者在應用程式中從一個畫面導覽到另一個畫面通常很有幫助。引導使用者瀏覽應用程式的一種常見技巧是將元件從一個畫面動畫到下一個畫面。這會建立連接兩個畫面的視覺錨點。

使用 Hero 元件來將元件從一個畫面動畫到下一個畫面。此範例使用以下步驟

  1. 建立兩個顯示相同圖片的畫面。
  2. 在第一個畫面中新增 Hero 元件。
  3. 在第二個畫面中新增 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 元件

#

若要完成與第一個畫面的連接,請使用與第一個畫面中的 Hero 具有相同 tagHero 元件包裝第二個畫面上的 Image

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',
            ),
          ),
        ),
      ),
    );
  }
}