今回は「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は異なっていても問題ありません。
以上です。