Hero Animation: Transisi Antar Halaman
Buat gambar produk terbang mulus dari daftar ke detail dengan Hero widget yang simpel.
Efek "terbang" antar halaman
Pernah lihat di aplikasi marketplace: ketuk foto produk di daftar, fotonya membesar terbang ke halaman detail. Itu Hero animation. Flutter menyediakannya hampir gratis lewat widget Hero.
Cara pakai: tag yang sama
Kuncinya adalah dua widget Hero dengan tag yang sama di halaman asal dan tujuan:
// Halaman daftar
ListView.builder(
itemCount: produk.length,
itemBuilder: (context, i) {
final p = produk[i];
return ListTile(
leading: Hero(
tag: 'gambar-${p.id}',
child: Image.network(p.gambarUrl, width: 56, height: 56, fit: BoxFit.cover),
),
title: Text(p.nama),
onTap: () => Navigator.push(
context,
MaterialPageRoute(builder: (_) => HalamanDetail(produk: p)),
),
);
},
);
// Halaman detail
class HalamanDetail extends StatelessWidget {
final Produk produk;
const HalamanDetail({super.key, required this.produk});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(produk.nama)),
body: Column(
children: [
Hero(
tag: 'gambar-${produk.id}',
child: Image.network(produk.gambarUrl, height: 280, width: double.infinity, fit: BoxFit.cover),
),
Padding(
padding: const EdgeInsets.all(16),
child: Text(produk.nama, style: const TextStyle(fontSize: 22)),
),
],
),
);
}
}Saat navigasi terjadi, Flutter otomatis menganimasikan widget dari posisi dan ukuran asal ke posisi dan ukuran tujuan. Tag harus unik per item, makanya digabung dengan id produk.
Kustomisasi penerbangan
Secara default hero terbang lurus. Kamu bisa mengatur kurva dan perilaku lewat flightShuttleBuilder atau membungkus dengan HeroMode untuk menonaktifkan sementara:
Hero(
tag: 'gambar-${produk.id}',
flightShuttleBuilder: (context, anim, direction, fromCtx, toCtx) {
return ScaleTransition(scale: anim, child: toCtx.widget);
},
child: Image.network(produk.gambarUrl),
)Batasan dan jebakan
Hero bekerja paling baik untuk widget yang secara visual mirip di kedua halaman (biasanya gambar). Jangan memakai Hero untuk teks panjang atau layout kompleks karena hasil morphing-nya bisa aneh. Dan pastikan tag unik: dua Hero dengan tag sama di halaman yang sama menyebabkan error atau animasi ke widget yang salah.
Catatan teknis: Hero animation memakai overlay selama transisi. Kalau halaman tujuan memuat gambar network yang belum ter-cache, hero akan terbang sebagai kotak kosong lalu gambar muncul belakangan, merusak efeknya. Solusinya: precache gambar dengan
precacheImage(NetworkImage(url), context)di halaman daftar, atau pakai thumbnail kecil yang sudah dimuat sebagai child Hero.