Pada kesempatan ini kita akan membahas cara menggunakan Hero Animation di Flutter. Hero Animasi merupakan sebuah element transisi yang bergerak melayang saat berpindah dari satu layar ke layar lainnya. Contoh tampilan hero seperti gambar dibawah ini
Tutorial ini sebagai lanjutan dari navigasi routing, jadi apabila anda belum mengetahui dasar-dasar routing silahkan baca terlebih dahulu pembahasan routing pada flutter disini
Daftar Isi
Pengenalan Hero Animation
Hero Animation bisa dikatakan merupakan salah satu animasi paling mudah dan sederhana di flutter. Caranya yaitu hanya dengan menggunakan class Hero pada kedua item (awal dan akhir) dan dihubungkan dengan properti tag yang memilik nilai yang sama. Contoh sederhana penggunaan Hero widget seperti dibawah ini:
Hero(
tag: "ContohTag",
child: Icon(
Icons.airport_shuttle,
size: 100.0,
),
),
Kedua pasangan masing element harus memiliki value tag yang sama dan bersifat unik. Sebagai contoh kita akan membuat transisi icon mobil dimana posisi awal mobil berada di pojok kiri atas dan akan bergerak ketengah saat berpindah ke layar selanjutnya. Contoh code lengkapnya seperti ini
main.dart
import 'package:flutter/material.dart'; void main() { runApp(MaterialApp( home: HomePage(), )); } class HomePage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Belajar Routing'), ), body: InkWell( onTap: () { Navigator.push( context, PageRouteBuilder( transitionDuration: Duration(seconds: 1), pageBuilder: (_, __, ___) => AboutPage(), ), ); }, child: Hero( tag: "ContohTag", child: Icon( Icons.airport_shuttle, size: 100.0, ), ), ), ); } } class AboutPage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Halaman Kedua'), ), body: Center( child: InkWell( onTap: () { Navigator.pop(context); }, child: Hero( tag: "ContohTag", child: Icon( Icons.airport_shuttle, size: 100.0, ), ), ), ), ); } }
Perhatikan tag pada Hero widget dimana nilainya sama-sama menggunakan string dengan value “ContohTag“. Hasilnya seperti gambar dibawah ini
Merubah Widget Hero saat Transisi
Kita juga dapat merubah tampilan widget saat proses transisi dengan menggunakan properti flightShuttleBuilder.
Hero(
tag: "ContohTag",
child: Icon(
Icons.airport_shuttle,
size: 100.0,
),
flightShuttleBuilder:
(flightContext, animation, direction, fromContext, toContext) {
return Icon( Icons.local_airport, size: 100.0, );
},
),
Dengan properti flightShuttleBuilder kita juga dapat merubah widget push dan pop dengan cara membedakan widget berdasarkan Hero direction
if (direction == HeroFlightDirection.push) {
return Icon(
Icons.local_airport,
size: 100.0,
);
} else if (direction == HeroFlightDirection.pop) {
return Icon(
Icons.local_airport,
size: 60.0,
);
}
Kode lengkapnya dibawah ini :
main.dart
import 'package:flutter/material.dart'; void main() { runApp(MaterialApp( home: HomePage(), )); } class HomePage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Belajar Hero'), ), body: InkWell( onTap: () { Navigator.push( context, PageRouteBuilder( transitionDuration: Duration(seconds: 1), pageBuilder: (_, __, ___) => AboutPage(), ), ); }, child: Hero( tag: "ContohTag", child: Icon( Icons.airport_shuttle, size: 100.0, ), flightShuttleBuilder: (flightContext, animation, direction, fromContext, toContext) { if (direction == HeroFlightDirection.push) { return Icon( Icons.local_airport, size: 100.0, ); } else if (direction == HeroFlightDirection.pop) { return Icon( Icons.local_airport, size: 60.0, ); } }, ), ), ); } } class AboutPage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Halaman Kedua'), ), body: Center( child: InkWell( onTap: () { Navigator.pop(context); }, child: Hero( tag: "ContohTag", child: Icon( Icons.home, size: 100.0, ), ), ), ), ); } }
Menambahkan placeholder
Untuk menambahkan placeholder di Hero, kita dapat menggunakan properti placeholderBuilder
Hero(
tag: "ContohTag",
child: Icon(
Icons.airport_shuttle,
size: 100.0,
),
placeholderBuilder: (context, widget) {
return Container(
height: 110.0,
width: 110.0,
child: CircularProgressIndicator(),
);
},
),
Hero + Transition Effect + Generate Route
Menggunakan Hero Animasi dengan GenerateRoute juga sama seperti cara-cara diatas. Berikut contoh penggunaan Hero animasi yang digabungkan dengan Fade Transition Effect menggunakan generate route
Struktur File
├── lib
│ ├── main.dart
│ ├── pixabay-data.dart
│ ├── routes.dart
│ └── screen.dart
main.dart
import 'package:flutter/material.dart'; import 'package:belajar_flutter/routes.dart'; void main() { runApp(MaterialApp( onGenerateRoute: RouteGenerator.generateRoute, )); }
routes.dart
import 'package:flutter/material.dart'; import 'package:belajar_flutter/screen.dart'; class RouteGenerator { static Route<dynamic> generateRoute(RouteSettings settings) { final args = settings.arguments; switch (settings.name) { case '/': return MaterialPageRoute(builder: (_) => HomePage()); case '/detail': return PageRouteBuilder( pageBuilder: (_, __, ___) => DetailPage(args), transitionDuration: Duration(milliseconds: 700), transitionsBuilder: (_, animation, secondAnimation, child) { return FadeTransition(opacity: animation, child: child); }, ); default: return _errorRoute(); } } static Route<dynamic> _errorRoute() { return MaterialPageRoute(builder: (_) { return Scaffold( appBar: AppBar(title: Text("Error")), body: Center(child: Text('Error page')), ); }); } }
screen.dart
import 'package:flutter/material.dart'; import 'package:belajar_flutter/pixabay-data.dart'; class HomePage extends StatefulWidget { @override _HomePageState createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { @override void initState() { ImageData.init(); super.initState(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Belajar Animasi Hero'), ), body: ListView.separated( itemCount: ImageData.pixabay.length, itemBuilder: (_, index) => GestureDetector( onTap: () { Navigator.pushNamed(context, '/detail', arguments: ImageData.pixabay[index]); }, child: ListTile( leading: Hero( tag: ImageData.pixabay[index].id, child: Image.network(ImageData.pixabay[index].imageLarge), transitionOnUserGestures: true, ), title: Text(ImageData.pixabay[index].title), subtitle: Text(ImageData.pixabay[index].author), ), ), separatorBuilder: (context, position) { return Divider(); }), ); } } class DetailPage extends StatelessWidget { final pixabay; DetailPage(this.pixabay); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Detail Gambar'), ), body: Center( child: Hero( tag: pixabay.id, child: Image.network(pixabay.imageLarge), ), ), ); } }
pixabay-data.dart
class ImageData { int id; String title; String author; String imageLarge; ImageData({this.id, this.title, this.author, this.imageLarge}); static List<ImageData> pixabay; ImageData.init() { pixabay = List(); pixabay.add( ImageData( id: 1, title: 'Tupai', author: 'Capri23auto', imageLarge: 'https://pixabay.com/get/53e5d1464c51a414f6da8c7dda793676173bd7e15a596c48702672d39548c459b9_1280.jpg'), ); pixabay.add( ImageData( id: 2, title: 'Anggur', author: 'NickyPe', imageLarge: 'https://pixabay.com/get/53e5d0424950a914f6da8c7dda793676173bd7e15a596c48702672d39548c459b9_1280.jpg'), ); pixabay.add( ImageData( id: 3, title: 'Pemandangan', author: 'Sonyuser', imageLarge: 'https://pixabay.com/get/53e5d6474956ad14f6da8c7dda793676173bd7e15a596c48702672d39548c459b9_1280.jpg'), ); pixabay.add( ImageData( id: 4, title: 'Kucing Kuning', author: 'Alexas_Fotos', imageLarge: 'https://pixabay.com/get/53e5d0434a51af14f6da8c7dda793676173bd7e15a596c48702672d39548c459b9_1280.jpg'), ); pixabay.add( ImageData( id: 5, title: 'Burung', author: 'Derweg', imageLarge: 'https://pixabay.com/get/53e5d1454c53ac14f6da8c7dda793676173bd7e15a596c48702672d39548c459b9_1280.jpg'), ); } }
Tampilan kode diatas akan menjadi seperti gambar dibawah ini
Penutupan
Menggunakan Hero Animation di Flutter cukup mudah namun tentu pembahasan diatas hanya dasar saja. Untuk penjelasan transition effect kita akan coba bahas dikesempatan lain.
Selamat Mencoba 🙂
Referensi :
https://api.flutter.dev/flutter/widgets/Hero-class.html
thanks ilmunya min.. sangat bermanfaat