Skip to main content

Navigasi dan Hero Animation Flutter

Pada aplikasi mobile, sering kali kita memiliki banyak halaman atau layar.
Proses perpindahan antar layar tersebut dinamakan navigasi.

Hero Animation adalah animasi bawaan flutter yang dapat langsung digunakan.

Jenis Navigasi

Pada tahapan ini kita akan coba membahas beberapa metode navigasi yang biasa digunakan.

info
  • Basic Navigation
  • Named Navigation
  • Routed Navigation

Prinsip Navigasi

Ada prinsip dasar terkait navigasi, yaitu stack:

Konsep

Ada 2 Jenis Stack:

  • Pop
    • Menumpukkan Stack atau Tumpukan Baru
  • Push
    • Membuang Stack Teratas

Contoh Pop:

Navigasi

Contoh Push:

alt

Struktur Project

Create Project

lib/screens/pertama.dart
import 'package:belajar_navigasi/screens/kedua.dart';import 'package:flutter/material.dart';class LayarPertama extends StatelessWidget {  const LayarPertama({Key? key}) : super(key: key);    Widget build(BuildContext context) {    return Scaffold(      appBar: AppBar(        title: const Text('Layar Pertama'),      ),      body: Center(        child: ElevatedButton(          child: const Text('Ke Layar 2'),          onPressed: () {            // Pada Line ini akan kita isi Perintah Navigasi Push          },        ),      ),    );  }}
lib/screens/kedua.dart
import 'package:flutter/material.dart';class LayarKedua extends StatelessWidget {  const LayarKedua({Key? key}) : super(key: key);    Widget build(BuildContext context) {    return Scaffold(      appBar: AppBar(        title: const Text('Layar Kedua'),      ),      body: Center(        child: ElevatedButton(          child: const Text('Kembali'),          onPressed: () {            // Pada Line ini akan kita isi Perintah Navigasi Pop          },        ),      ),    );  }}
lib/main.dart
import 'package:belajar_navigasi/screens/pertama.dart';import 'package:flutter/material.dart';void main() {  runApp(const MyApp());}class MyApp extends StatelessWidget {  const MyApp({Key? key}) : super(key: key);    Widget build(BuildContext context) {    return MaterialApp(      title: 'Flutter Demo',      theme: ThemeData(        primarySwatch: Colors.blue      ),      home: const LayarPertama()    );  }}

Basic Navigation

info
  • Berpindah antara widget/screen 1 ke widget lain nya
  • Menggunakan class Navigator dari API Flutter
  • Method push → menuju layar baru
  • Method pop → kembali ke layar sebelumnya

Push

lib/screens/pertama.dart
import 'package:belajar_navigasi/screens/kedua.dart';import 'package:flutter/material.dart';class LayarPertama extends StatelessWidget {  const LayarPertama({Key? key}) : super(key: key);    Widget build(BuildContext context) {    return Scaffold(      appBar: AppBar(        title: const Text('Layar Pertama'),      ),      body: Center(        child: ElevatedButton(          child: const Text('Ke Layar 2'),          onPressed: () {            Navigator.push(              context,              MaterialPageRoute(builder: (context) => const LayarKedua())            );          },        ),      ),    );  }}

Pop

lib/screens/kedua.dart
import 'package:flutter/material.dart';class LayarKedua extends StatelessWidget {  const LayarKedua({Key? key}) : super(key: key);    Widget build(BuildContext context) {    return Scaffold(      appBar: AppBar(        title: const Text('Layar Kedua'),      ),      body: Center(        child: ElevatedButton(          child: const Text('Kembali'),          onPressed: () {            Navigator.pop(context);          },        ),      ),    );  }}

With Data

Pada jenis navigasi ini kita dapat mengirim data dengan cara:

  • Menggunakan Navigator
  • Menambahkan Argument ke Widget/Layar Tujuan
  • Mendeklarasikan Variable Penerima Argument tersebut di Layar Tujuan
lib/screens/kedua.dart
import 'package:flutter/material.dart';class LayarKedua extends StatelessWidget {  const LayarKedua({Key? key, required this.kutipan}) : super(key: key);  final String kutipan;    Widget build(BuildContext context) {    return Scaffold(      appBar: AppBar(        title: const Text('Layar Kedua'),      ),      body: Container(        alignment: Alignment.center,        child: Column(          mainAxisAlignment: MainAxisAlignment.center,          children: <Widget>[            Text(              kutipan,              style: const TextStyle(                fontSize: 20              ),            ),            ElevatedButton(              onPressed: () {                Navigator.pop(context);              },               child: const Text('Kembali')            )          ],        ),      )    );  }}
lib/screens/pertama.dart
import 'package:belajar_navigasi/screens/kedua.dart';import 'package:flutter/material.dart';class LayarPertama extends StatelessWidget {  const LayarPertama({Key? key}) : super(key: key);    Widget build(BuildContext context) {    return Scaffold(      appBar: AppBar(        title: const Text('Layar Pertama'),      ),      body: Center(        child: ElevatedButton(          child: const Text('Ke Layar 2'),          onPressed: () {            Navigator.push(              context,              MaterialPageRoute(builder: (context) => const LayarKedua(kutipan: 'Data Dari Layar 1'))            );          },        ),      ),    );  }}

Hasil

alt

Named Routed Navigation

info
  • Membuat Route di bagian awal Aplikasi
    • Ada initialRoute → Route yang akan di eksekusi pertama kali
    • ada routes → daftar route yang kita buat
  • Method pushNamed → menuju layar baru menggunakan nama rute

Define Route

lib/main.dart
import 'package:belajar_navigasi/screens/kedua.dart';import 'package:belajar_navigasi/screens/pertama.dart';import 'package:flutter/material.dart';void main() {  runApp(const MyApp());}class MyApp extends StatelessWidget {  const MyApp({Key? key}) : super(key: key);    Widget build(BuildContext context) {    return MaterialApp(      title: 'Flutter Demo',      theme: ThemeData(        primarySwatch: Colors.blue      ),      initialRoute: '/',      routes: {        '/': (context) => const LayarPertama(),        '/kedua': (context) => const LayarKedua()      }    );  }}

Push

lib/screens/pertama.dart
import 'package:belajar_navigasi/screens/kedua.dart';import 'package:flutter/material.dart';class LayarPertama extends StatelessWidget {  const LayarPertama({Key? key}) : super(key: key);    Widget build(BuildContext context) {    return Scaffold(      appBar: AppBar(        title: const Text('Layar Pertama'),      ),      body: Center(        child: ElevatedButton(          child: const Text('Ke Layar 2'),          onPressed: () {            Navigator.pushNamed(context, '/kedua');          },        ),      ),    );  }}

With Data

Pada jenis navigasi ini kita dapat mengirim data dengan cara:

  • Menggunakan property argument
  • Menggunakan method ModalRoute.of()
    • mengembalikan route sekarang dengan arguments nya
  • Deklarasikan Variable di widget tujuan
    • untuk menampung nilai
lib/screens/pertama.dart
import 'package:belajar_navigasi/screens/kedua.dart';import 'package:flutter/material.dart';class LayarPertama extends StatelessWidget {  const LayarPertama({Key? key}) : super(key: key);    Widget build(BuildContext context) {    return Scaffold(      appBar: AppBar(        title: const Text('Layar Pertama'),      ),      body: Center(        child: ElevatedButton(          child: const Text('Ke Layar 2'),          onPressed: () {            Navigator.pushNamed(              context,               '/kedua',              arguments: 'Data Dari Layar 1'            );          },        ),      ),    );  }}
lib/screens/kedua.dart
import 'package:flutter/material.dart';class LayarKedua extends StatelessWidget {  const LayarKedua({Key? key}) : super(key: key);    Widget build(BuildContext context) {    // Ambil Data Argument    final args = ModalRoute.of(context)!.settings.arguments as String;    return Scaffold(      appBar: AppBar(        title: const Text('Layar Kedua'),      ),      body: Container(        alignment: Alignment.center,        child: Column(          mainAxisAlignment: MainAxisAlignment.center,          children: <Widget>[            Text(              args,              style: const TextStyle(                fontSize: 20              ),            ),            ElevatedButton(              onPressed: () {                Navigator.pop(context);              },               child: const Text('Kembali')            )          ],        ),      )    );  }}

Hasil

alt

Hero Animation

Animasi Default dari Flutter

lib/screens/pertama.dart
import 'package:belajar_navigasi/screens/kedua.dart';import 'package:flutter/material.dart';class LayarPertama extends StatelessWidget {  const LayarPertama({Key? key}) : super(key: key);    Widget build(BuildContext context) {    return Scaffold(      appBar: AppBar(        title: const Text('Layar Pertama'),      ),      body: Container(        padding: EdgeInsets.all(10),        child: GestureDetector(          child: Hero(            tag: 'gambarHero',            child: Image.network('https://picsum.photos/250?image=9'),          ),          onTap: () {            Navigator.pushNamed(              context,               '/kedua',              arguments: 'Data Dari Layar 1'            );          },        ),      )    );  }}
lib/screens/kedua.dart
import 'package:flutter/material.dart';class LayarKedua extends StatelessWidget {  const LayarKedua({Key? key}) : super(key: key);    Widget build(BuildContext context) {    // Ambil Data Argument    final args = ModalRoute.of(context)!.settings.arguments as String;    return Scaffold(      appBar: AppBar(        title: const Text('Layar Kedua'),      ),      body: Container(        alignment: Alignment.center,        child: Column(          mainAxisAlignment: MainAxisAlignment.center,          children: <Widget>[            Hero(              tag: 'gambarHero',               child: Image.network('https://picsum.photos/250?image=9')            ),            Text(              args,              style: const TextStyle(                fontSize: 20              ),            ),            ElevatedButton(              onPressed: () {                Navigator.pop(context);              },               child: const Text('Kembali')            )          ],        ),      )    );  }}

Hasil

alt