6
4

More than 1 year has passed since last update.

【Flutter】HeroWidgetでリッチな画面遷移を実装する

Last updated at Posted at 2022-06-22

HeroWidgetを使用して簡単にリッチな画面遷移を実装していきます。

動作

 

これだけ

HeroWidgetは指定した2つのWidget間で自動的にトランジションを作成してくれるので、Heroで囲った2つのWidgetを用意。

class MyHomePage extends StatelessWidget {
// ↓一つ目
         GestureDetector(
        onTap: () {
          Navigator.of(context).push(
            MaterialPageRoute(
              fullscreenDialog: true,
              builder: (BuildContext context) => DetailPage(),
            ),
          );
        },
        child: Card(
          margin: const EdgeInsets.all(24),
          elevation: 4.0,
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(12.0),
          ),
          clipBehavior: Clip.antiAlias,
          child: Hero(
            tag: 'uniqueTag',
            child: Image.network(
              'https://images.unsplash.com/photo-1595581831735-ec7a54193665?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1729&q=80',
              fit: BoxFit.cover,
              // height: 100,
            ),
          ),
        ),
      ),
}

class DetailPage extends StatelessWidget {
// 二つ目
                Hero(
                  tag: 'uniqueTag',
                  child: GestureDetector(
                    onTap: () => Navigator.pop(context),
                    child: Image.network(
                      'https://images.unsplash.com/photo-1595581831735-ec7a54193665?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1729&q=80',
                      fit: BoxFit.cover,
                    ),
                  ),
                ),

}

HeroWidgetのtagプロパティには同一のtag名を指定してください。あとは画面遷移を実装するだけで動画のようにリッチな画面遷移が実装できます。

活用例

ユーザープロフィールを表示させる時とかに使えそうです。tagプロパティにはインデックスを指定しています。
 

全体コード

コピペで動きます。


class MyHomePage extends StatelessWidget {
  const MyHomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Hero Sample'),
      ),
      body: GestureDetector(
        onTap: () {
          Navigator.of(context).push(
            MaterialPageRoute(
              fullscreenDialog: true,
              builder: (BuildContext context) => DetailPage(),
            ),
          );
        },
        child: Card(
          margin: const EdgeInsets.all(24),
          elevation: 4.0,
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(12.0),
          ),
          clipBehavior: Clip.antiAlias,
          child: Hero(
            tag: 'uniqueTag',
            child: Image.network(
              'https://images.unsplash.com/photo-1595581831735-ec7a54193665?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1729&q=80',
              fit: BoxFit.cover,
              // height: 100,
            ),
          ),
        ),
      ),
    );
  }
}

class DetailPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: <Widget>[
          Center(
            child: Column(
              children: <Widget>[
                Hero(
                  tag: 'uniqueTag',
                  child: GestureDetector(
                    onTap: () => Navigator.pop(context),
                    child: Image.network(
                      'https://images.unsplash.com/photo-1595581831735-ec7a54193665?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1729&q=80',
                      fit: BoxFit.cover,
                    ),
                  ),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

手軽におしゃれな画面遷移を実装することができるので皆さんも実装してみてはいかがでしょうか。

参考

6
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
4