Udemyセール開催中! 対象コースが1,220円から

【Flutter】Hero|画面遷移中もアニメーションでWidgetを表示させる

今回は「Hero」の基本的な使い方について紹介します。

Navigatorで画面遷移する場合、現在のスクリーンコンテンツが消えて新しいコンテンツが表示されてしまいます。ですが、Heroを使えば指定したWidgetを画面遷移中もアニメーションで表示できます。(上動画参照)

目次

下準備

画面遷移を行うための下準備として下の初期コードを使用します。

最終的にHeroを使って緑色のContainerを画面遷移中もアニメーションで表示されるようにします。

//初期ソース
import 'package:flutter/material.dart';

void main() => runApp(MaterialApp(home: HomeScreen()));

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Home'),
      ),
      body: GestureDetector(
        onTap: () {
          Navigator.push(
            context,
            MaterialPageRoute(builder: (context) => const SecondScreen()),
          );
        },
        child: Container(
          width: 100,
          height: 100,
          color: Colors.green,
        ),
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Second'),
      ),
      body: Center(
        child: GestureDetector(
          onTap: () {
            Navigator.pop(context);
          },
          child: Container(
            width: 200,
            height: 200,
            color: Colors.green,
          ),
        ),
      ),
    );
  }
}

Heroの使い方

//HomeScreen
Hero(
  tag: 'boxHero',
  child: Container(
    width: 100,
    height: 100,
    color: Colors.green,
  ),
),

//SecondScreen
Hero(
  tag: 'boxHero',
  child: Container(
    width: 200,
    height: 200,
    color: Colors.green,
  ),
),

画面遷移中にアニメーションで表示させたいWidgetを「Hero」のchildプロパティで指定し、tagプロパティでタグをつけます。タグは遷移前と遷移先で同じ名前にします。

これで完了です。

完成コード

これで画面遷移中も指定したWidgetをアニメーションで表示できるようになりました。

//完成ソース
import 'package:flutter/material.dart';

void main() => runApp(MaterialApp(home: HomeScreen()));

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Home'),
      ),
      body: GestureDetector(
        onTap: () {
          Navigator.push(
            context,
            MaterialPageRoute(builder: (context) => const SecondScreen()),
          );
        },
        child: Hero(
          tag: 'boxHero',
          child: Container(
            width: 100,
            height: 100,
            color: Colors.green,
          ),
        ),
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Second'),
      ),
      body: Center(
        child: GestureDetector(
          onTap: () {
            Navigator.pop(context);
          },
          child: Hero(
            tag: 'boxHero',
            child: Container(
              width: 200,
              height: 200,
              color: Colors.green,
            ),
          ),
        ),
      ),
    );
  }
}

おまけ:Widgetは異なっていても大丈夫

tagが同じであればWidgetは異なっていても問題ありません。

以上です。

参考

  • URLをコピーしました!
目次
閉じる