Memahami Navigasi Routing di Flutter

Pada kesempatan ini kita akan coba membahas navigasi routing di Flutter. Dalam sebuah aplikasi mobile biasanya memiliki full-screen elemen yang disebut “screen” atau “page”. Di Flutter, elemen ini disebut route dan dikelola oleh widget Navigator. Widget navigator berfungsi untuk menampilkan konten ke halaman atau layar baru. Jika pada native Android, Navigator route dinamakan dengan activity dan di iOS sebagai viewController.

Widget Navigator bekerja seperti tumpukan layar (stack), ia menggunakan prinsip LIFO (Last-In, First-Out). Ada dua method yang dapat digunakan pada Navigator widget yaitu :

  1. Navigator.push (): Metode push digunakan untuk menambahkan rute lain ke atas tumpukan screen (stack) saat ini. Halaman baru ditampilkan di atas halaman sebelumnya.
  2. Navigator.pop (): Metode pop menghapus rute paling atas dari tumpukan. Ini menampilkan halaman sebelumnya kepada pengguna.

Simple Routing Flutter

Penggunaan widget Navigator untuk routing di flutter yaitu seperti dibawah ini

Navigator.push(
    context, 
   	MaterialPageRoute(builder: (context) {
  		return AboutPage()
  	})
);

Dalam contoh penerapannya, kita akan membuat routing sederhana menggunakan metode Navigator.push untuk navigasi ke layar baru dan Navigator.pop untuk kembali ke layar sebelumnya.

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: Center(
        child: RaisedButton(
          onPressed: () {
            Route route = MaterialPageRoute(builder: (context) => AboutPage());
            Navigator.push(context, route);
          },
          child: Text('Tap Untuk ke AboutPage'),
        ),
      ),
    );
  }
}

class AboutPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Tentang Aplikasi'),
      ),
      body: Center(
        child: RaisedButton(
          onPressed: () {
            Navigator.pop(context);
          },
          child: Text('Kembali'),
        ),
      ),
    );
  }
}

Contoh kode di atas membuat dua stateless widget dimana halaman awal menggunakan HomePage dan berpindah ke AboutPage saat tombol di tap. Tampilannya seperti gambar di bawah ini

contoh routing flutter
Gambar 1.1 : Contoh Navigasi Routing di Flutter

Named Routing

Sesuai namanya, Named Routing yaitu memberi nama pada routing dengan tujuan untuk mempermudah dalam membaca dan menentukan arah dari suatu navigasi. Sedikit berbeda dengan simple routing, disini kita akan menggunakan Navigator.pushNamed untuk menuju ke halaman baru namun tetap menggunakan Navigator.pop untuk kembali ke halaman sebelumnya.

Navigator.pushNamed membutuhkan dua properti wajib yaitu context dan string sebagai nama routenya. Kita juga dapat mengirim parameter object ke dalam route

Navigator.pushNamed(context, String, {Object});

Syntax:

import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
    initialRoute: '/',
    routes: <String, WidgetBuilder>{
      '/': (context) => HomePage(),
      '/about': (context) => AboutPage(),
    },
  ));
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Belajar Routing'),
      ),
      body: Center(
        child: RaisedButton(
          onPressed: () {
            Navigator.pushNamed(context, '/about');
          },
          child: Text('Tap Untuk ke AboutPage'),
        ),
      ),
    );
  }
}

class AboutPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Tentang Aplikasi'),
      ),
      body: Center(
        child: RaisedButton(
          onPressed: () {
            Navigator.pop(context);
          },
          child: Text('Kembali'),
        ),
      ),
    );
  }
}

Contoh kode diatas akan sama dengan gambar 1.1.

Perhatikan potongan kode pada main function dibawah ini

void main() {
  runApp(MaterialApp(
    initialRoute: '/',
    routes: <String, WidgetBuilder>{
      '/': (context) => HomePage(),
      '/about': (context) => AboutPage(),
    },
  ));
}

method initialRoute tidak wajib jika dalam routes kita memiliki “/”. Kita juga dapat menggunakan properti home sebagai initialRoute seperti di bawah ini.

void main() {
  runApp(MaterialApp(
    home: HomePage(),
    routes: <String, WidgetBuilder>{
      '/': (context) => HomePage(),
      '/about': (context) => AboutPage(),
    },
  ));
}

Route Generator

Meskipun named routing terlihat lebih baik dari simple routing, namun apabila ingin membuat aplikasi dengan skala yang cukup besar atau ingin mengatur animasi transisi dari tiap routing maka onGenerateRoute merupakan pilihan yang tepat. Dalam tutorial route generator ini kita akan coba memisahkan antara main, screen dan routing file

Main.dart

import 'package:flutter/material.dart';
import 'package:belajar_flutter/routes.dart';

void main() {
  runApp(MaterialApp(
    onGenerateRoute: RouteGenerator.generateRoute,
  ));
}

screen.dart

import 'package:flutter/material.dart';

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Belajar Routing'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            RaisedButton(
              onPressed: () {
                Navigator.pushNamed(context, '/about');
              },
              child: Text('Tap Untuk ke AboutPage'),
            ),
            RaisedButton(
              onPressed: () {
                Navigator.pushNamed(context, '/halaman-404');
              },
              child: Text('Tap Halaman lain'),
            ),
          ],
        ),
      ),
    );
  }
}

class AboutPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Tentang Aplikasi'),
      ),
      body: Center(
        child: RaisedButton(
          onPressed: () {
            Navigator.pop(context);
          },
          child: Text('Kembali'),
        ),
      ),
    );
  }
}

routes.dart

import 'package:flutter/material.dart';
import 'package:belajar_flutter/screen.dart';

class RouteGenerator {
  static Route<dynamic> generateRoute(RouteSettings settings) {
    // jika ingin mengirim argument
    // final args = settings.arguments; 

    switch (settings.name) {
      case '/':
        return MaterialPageRoute(builder: (_) => HomePage());
      case '/about':
        return MaterialPageRoute(builder: (_) => AboutPage());
        // return MaterialPageRoute(builder: (_) => AboutPage(args));
      default:
        return _errorRoute();
    }
  }

  static Route<dynamic> _errorRoute() {
    return MaterialPageRoute(builder: (_) {
      return Scaffold(
        appBar: AppBar(title: Text("Error")),
        body: Center(child: Text('Error page')),
      );
    });
  }
}

pada contoh diatas kita juga menambahkan error page dimana jika routing tidak ditemukan maka akan menampikan halaman error tersebut

Navigasi Routing di Flutter

Penutupan

Contoh diatas merupakan basic atau dasar navigasi routing di Flutter. Kita juga dapat menambahkan animasi transisi, parameter, dan kondisi lainnya. Penggunaan route generator lebih disarankan karena akan mempermudah dalam manage dan kostum route

Referensi :
https://flutter.dev/docs/cookbook/navigation/named-routes

Default image
Omadi Jaya
Fullstack developer, Software Engineer @ Depok, Indonesia

Leave a Reply