Pendahuluan
Tujuan Praktikum
- Membuat aplikasi yang dapat berpindah dari halaman satu ke halaman lain
- Membuat aplikasi yang dapat mengirim dan menerima data dari halaman lain
Routing
Pengertian
Routing atau Rute adalah sebuah sistem yang digunakan untuk mendefinisikan dan mengelola routes dalam aplikasi, setiap route didefinisikan sehingga Ketika akan memanggil halaman cukup dengan memanggil nama route tersebut, hal ini mempermudah dalam mengelola route tanpa harus membuat instance baru setiap kali akan memanggil suatu halaman.
Jenis - Jenis Routing
1. Navigator (Anonymous Routes)
Widget Navigation menampilkan halaman dengan konsep tumpukan menggunakan animasi transisi Ketika berpindah ke halaman, untuk berpindah ke halaman baru diakses melalui BuildContext dengan memanggil method seperti push() atau pop() secara langsung.
2. Named Routes
Named Routes atau Rute Bernama mengelola route pada widget MateriapApp atau CupertinoApp kemudian memanggilnya berdasarkan nama yang telah diberikan
3. Generated Routes
Generated Routes yang sebuah mekanisme mengelola routes dengan mengirimkan paremeter dan handle error.
4. Router / Navigator 2.0
Mekanisme pengelolaan routes ini digunakan jika aplikasi yang membutuhkan route yang komplek, biasanya digunakan Ketika membuat aplikasi web pada flutter.
Multiple Screen (Named Routes)
Pengertian
Saat kembali ke halaman sebelumnya, Flutter menggunakan pop() untuk menghapus halaman paling atas.
- Halaman Login
- Halaman Home
- Halaman Detail Produk
- Halaman Profile
Di Flutter, untuk berpindah antar halaman digunakan Navigator dan Routing.
- Navigator bertugas memindahkan (push) atau kembali (pop) dari satu halaman ke halaman lain
- Routing adalah sistem yang mengatur dan memberi nama setiap halaman agar bisa dipanggil dengan mudah.
Mengirim dan Menerima Data
Pengertian
Flutter memungkinkan kita mengirim data dari satu halaman ke halaman lain, contohnya:
- Dari halaman Home ke halaman Profile, mengirim data seperti username dan ID pengguna..
- Dari halaman Product List ke halaman Product Detail, mengirim data seperti nama produk dan harga.
Cara mengirim data ada 2 yaitu :
- Melalui Constructor yaitu data dikirim saat halaman baru dibuat
- Melalui Named Routes + Arguments yaitu data dikirim bersamaan dengan pemanggilan route.
Langkah Praktikum
1. Multiple screen
- Buat file dart baru, disini saya menamakannya MyNav.dart lalu isikan dengan kode ini
import 'package:flutter/material.dart';
void main() => runApp(const MyNav());
class MyNav extends StatelessWidget {
const MyNav({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
initialRoute: '/',
routes: {
'/': (context) => const Product(),
'/product_detail': (context) => const ProductDetail(),
},
);
}
}
class Product extends StatelessWidget {
const Product({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Produk')),
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, '/product_detail');
},
child: const Text('Go to Product Detail'),
),
),
);
}
}
class ProductDetail extends StatelessWidget {
const ProductDetail({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Product Detail')),
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.pop(context);
},
child: const Text('Back to Product'),
),
),
);
}
}
Berikut tampilan hasilnya.
Halaman Product
Halaman Product Detail
2. Mengirim dan Menerima Data antar Halaman
- Buat file dart baru, disini saya menamakannya MyProfile.dart lalu isikan dengan kode ini
import 'package:flutter/material.dart';
void main() => runApp(MyNav());
class MyNav extends StatelessWidget {
const MyNav({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
initialRoute: '/',
routes: {
'/': (context) => const HomePage(),
'/product': (context) => const MyProduct(),
},
);
}
}
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Home Page')),
body: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const MyProfile(id: 1, name: 'Galid'),
),
);
},
child: const Text('Profile'),
),
const SizedBox(width: 20),
ElevatedButton(
onPressed: () {
Navigator.pushNamed(
context,
'/product',
arguments: {'id': 101, 'name': 'Laptop'},
);
},
child: const Text('Product'),
),
],
),
),
);
}
}
class MyProfile extends StatelessWidget {
final int id;
final String name;
const MyProfile({super.key, required this.id, required this.name});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Profile')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [Text('ID: $id'), Text('Name: $name')],
),
),
);
}
}
class MyProduct extends StatelessWidget {
const MyProduct({super.key});
@override
Widget build(BuildContext context) {
final args = ModalRoute.of(context)!.settings.arguments as Map?;
final int id = args?['id'] ?? 0;
final String name = args?['name'] ?? 'Unknown';
return Scaffold(
appBar: AppBar(title: const Text('Product')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [Text('Product ID: $id'), Text('Product Name: $name')],
),
),
);
}
}
Berikut tampilan hasilnya.
Halaman Home
Halaman Profile menggunakan Constructor
Halaman Product menggunakan Named Routes
Tugas
Implementasi Basic Form Flutter
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Tugas Navigation & Routing',
initialRoute: '/',
routes: {
'/': (context) => const LoginPage(), // route '/' mengarah ke halaman Login
'/home': (context) => const HomePage(), // route '/home' mengarah ke halaman utama
},
);
}
}
//HALAMAN LOGIN
class LoginPage extends StatefulWidget {
const LoginPage({super.key});
@override
State createState() => _LoginPageState();
}
class _LoginPageState extends State {
// Controller digunakan untuk mengambil teks dari TextField
final TextEditingController _usernameController = TextEditingController();
final TextEditingController _passwordController = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Login Page')),
body: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// Input field untuk username
TextField(
controller: _usernameController, // menghubungkan controller
decoration: const InputDecoration(labelText: 'Username'),
),
const SizedBox(height: 15),
// Input field untuk password
TextField(
controller: _passwordController,
decoration: const InputDecoration(labelText: 'Password'),
obscureText: true, // agar teks password tidak terlihat
),
const SizedBox(height: 20),
// Tombol login
ElevatedButton(
onPressed: () {
// Ambil data dari TextField
String username = _usernameController.text;
String password = _passwordController.text;
// Pindah ke halaman Home sambil mengirim data username dan password
Navigator.pushNamed(
context,
'/home', // nama route tujuan
arguments: {
'username': username,
'password': password,
}, // data dikirim dalam bentuk Map
);
},
child: const Text('Login'),
),
],
),
),
);
}
}
//HALAMAN HOME
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
// Menerima data dari halaman Login menggunakan ModalRoute
final args = ModalRoute.of(context)!.settings.arguments as Map?;
// Jika data ada, ambil nilai username dan password
final username = args?['username'] ?? 'Unknown';
final password = args?['password'] ?? 'Not set';
return Scaffold(
appBar: AppBar(title: const Text('Home Page')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// Menampilkan data yang dikirim dari halaman Login
Text(
'Selamat Datang, $username!',
style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
const SizedBox(height: 10),
Text('Password Anda: $password'),
const SizedBox(height: 30),
const Text(
'Contoh Navigasi Menggunakan Bottom Navigation Bar:',
textAlign: TextAlign.center,
),
],
),
),
// BOTTOM NAVIGATION BAR
// Salah satu contoh konsep navigation & routing bawaan Flutter
bottomNavigationBar: BottomNavigationBar(
// Daftar menu yang muncul di bawah layar
items: const [
BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Home'),
BottomNavigationBarItem(icon: Icon(Icons.person), label: 'Profile'),
BottomNavigationBarItem(icon: Icon(Icons.settings), label: 'Settings'),
],
// Aksi ketika salah satu menu ditekan
onTap: (index) {
if (index == 0) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Menu Home ditekan')),
);
} else if (index == 1) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Menu Profile ditekan')),
);
} else if (index == 2) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Menu Settings ditekan')),
);
}
},
),
);
}
}
Berikut tampilan hasilnya.