Terakhir diperbarui: 03 Oktober 2024
Penulis: Habibie Ed Dien
Pada codelab ini, Anda akan mempelajari konsep dan praktik untuk dasar-dasar framework Flutter dengan menerapkan layout dan navigasi.
Setelah menyelesaikan codelab ini Anda akan mampu untuk:
Berikut merupakan sumber daya yang diperlukan untuk menyelesaikan praktikum ini:
Inti dari mekanisme tata letak Flutter adalah widget. Di Flutter, hampir semuanya adalah widget—bahkan model tata letak pun merupakan widget. Gambar, ikon, dan teks yang Anda lihat di aplikasi Flutter semuanya merupakan widget. Namun hal-hal yang tidak Anda lihat juga merupakan widget, seperti baris, kolom, dan kisi yang mengatur, membatasi, dan menyelaraskan widget yang terlihat.
Anda membuat tata letak dengan menyusun widget untuk membuat widget yang lebih kompleks. Misalnya, tangkapan layar pertama di bawah ini menunjukkan 3 ikon dengan label di bawah masing-masing ikon:
Tangkapan layar kedua menampilkan tata letak visual, memperlihatkan deretan 3 kolom yang setiap kolomnya berisi ikon dan label.
Berikut diagram pohon widget untuk UI ini:
Sebagian besar tampilannya akan terlihat seperti yang Anda harapkan, namun Anda mungkin bertanya-tanya tentang wadahnya (ditampilkan dalam warna merah muda). Kontainer adalah kelas widget yang memungkinkan Anda menyesuaikan widget turunannya. Gunakan Kontainer ketika Anda ingin menambahkan padding, margin, batas, atau warna latar belakang, untuk menyebutkan beberapa kemampuannya.
Dalam contoh ini, setiap widget Teks ditempatkan dalam Wadah untuk menambahkan margin. Seluruh Baris juga ditempatkan dalam Wadah untuk menambahkan bantalan di sekitar baris.
UI lainnya dalam contoh ini dikendalikan oleh properti. Atur warna Ikon menggunakan properti warnanya. Gunakan properti Text.style untuk mengatur font, warna, berat, dan sebagainya. Kolom dan baris memiliki properti yang memungkinkan Anda menentukan bagaimana turunannya disejajarkan secara vertikal atau horizontal, dan berapa banyak ruang yang harus ditempati oleh turunannya.
Selesaikan langkah-langkah praktikum berikut ini menggunakan editor Visual Studio Code (VS Code) atau Android Studio atau code editor lain kesukaan Anda.
Tampilan akhir yang akan Anda buat
Buatlah sebuah project flutter baru dengan nama layout_flutter. Atau sesuaikan style laporan praktikum yang Anda buat.
lib/main.dart
Buka file main.dart
lalu ganti dengan kode berikut. Isi nama dan NIM Anda di text title
.
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: 'Flutter layout: Nama dan NIM Anda',
home: Scaffold(
appBar: AppBar(
title: const Text('Flutter layout demo'),
),
body: const Center(
child: Text('Hello World'),
),
),
);
}
}
Langkah pertama adalah memecah tata letak menjadi elemen dasarnya:
Pertama, identifikasi elemen yang lebih besar. Dalam contoh ini, empat elemen disusun menjadi sebuah kolom: sebuah gambar, dua baris, dan satu blok teks.
Selanjutnya, buat diagram setiap baris. Baris pertama, disebut bagian Judul, memiliki 3 anak: kolom teks, ikon bintang, dan angka. Anak pertamanya, kolom, berisi 2 baris teks. Kolom pertama itu memakan banyak ruang, sehingga harus dibungkus dengan widget yang Diperluas.
Baris kedua, disebut bagian Tombol, juga memiliki 3 anak: setiap anak merupakan kolom yang berisi ikon dan teks.
Setelah tata letak telah dibuat diagramnya, cara termudah adalah dengan menerapkan pendekatan bottom-up. Untuk meminimalkan kebingungan visual dari kode tata letak yang banyak bertumpuk, tempatkan beberapa implementasi dalam variabel dan fungsi.
Pertama, Anda akan membuat kolom bagian kiri pada judul. Tambahkan kode berikut di bagian atas metode build()
di dalam kelas MyApp
:
Widget titleSection = Container(
padding: const EdgeInsets.all(...),
child: Row(
children: [
Expanded(
/* soal 1*/
child: Column(
crossAxisAlignment: ...,
children: [
/* soal 2*/
Container(
padding: const EdgeInsets.only(bottom: ...),
child: const Text(
'Wisata Gunung di Batu',
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
),
Text(
'Batu, Malang, Indonesia',
style: TextStyle(...),
),
],
),
),
/* soal 3*/
Icon(
...,
color: ...,
),
const Text(...),
],
),
);
/* soal 1 */ Letakkan widget Column
di dalam widget Expanded
agar menyesuaikan ruang yang tersisa di dalam widget Row
. Tambahkan properti crossAxisAlignment
ke CrossAxisAlignment.start
sehingga posisi kolom berada di awal baris.
/* soal 2 */ Letakkan baris pertama teks di dalam Container
sehingga memungkinkan Anda untuk menambahkan padding = 8. Teks ‘Batu, Malang, Indonesia
' di dalam Column
, set warna menjadi abu-abu.
/* soal 3 */ Dua item terakhir di baris judul adalah ikon bintang, set dengan warna merah, dan teks "41". Seluruh baris ada di dalam Container
dan beri padding di sepanjang setiap tepinya sebesar 32 piksel. Kemudian ganti isi body text ‘Hello World'
dengan variabel titleSection
seperti berikut:
Selesaikan langkah-langkah praktikum berikut ini dengan melanjutkan dari praktikum sebelumnya.
Bagian tombol berisi 3 kolom yang menggunakan tata letak yang sama—sebuah ikon di atas baris teks. Kolom pada baris ini diberi jarak yang sama, dan teks serta ikon diberi warna primer.
Karena kode untuk membangun setiap kolom hampir sama, buatlah metode pembantu pribadi bernama buildButtonColumn()
, yang mempunyai parameter warna, Icon
dan Text
, sehingga dapat mengembalikan kolom dengan widgetnya sesuai dengan warna tertentu.
lib/main.dart (_buildButtonColumn)
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
// ···
}
Column _buildButtonColumn(Color color, IconData icon, String label) {
return Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(icon, color: color),
Container(
margin: const EdgeInsets.only(top: 8),
child: Text(
label,
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w400,
color: color,
),
),
),
],
);
}
}
Buat Fungsi untuk menambahkan ikon langsung ke kolom. Teks berada di dalam Container
dengan margin hanya di bagian atas, yang memisahkan teks dari ikon.
Bangun baris yang berisi kolom-kolom ini dengan memanggil fungsi dan set warna, Icon
, dan teks khusus melalui parameter ke kolom tersebut. Sejajarkan kolom di sepanjang sumbu utama menggunakan MainAxisAlignment.spaceEvenly
untuk mengatur ruang kosong secara merata sebelum, di antara, dan setelah setiap kolom. Tambahkan kode berikut tepat di bawah deklarasi titleSection
di dalam metode build()
:
lib/main.dart (buttonSection)
Color color = Theme.of(context).primaryColor;
Widget buttonSection = Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
_buildButtonColumn(color, Icons.call, 'CALL'),
_buildButtonColumn(color, Icons.near_me, 'ROUTE'),
_buildButtonColumn(color, Icons.share, 'SHARE'),
],
);
Tambahkan variabel buttonSection
ke dalam body
seperti berikut:
Selesaikan langkah-langkah praktikum berikut ini dengan melanjutkan dari praktikum sebelumnya.
Tentukan bagian teks sebagai variabel. Masukkan teks ke dalam Container
dan tambahkan padding di sepanjang setiap tepinya. Tambahkan kode berikut tepat di bawah deklarasi buttonSection
:
Widget textSection = Container(
padding: const EdgeInsets.all(32),
child: const Text(
'Carilah teks di internet yang sesuai '
'dengan foto atau tempat wisata yang ingin '
'Anda tampilkan. '
'Tambahkan nama dan NIM Anda sebagai '
'identitas hasil pekerjaan Anda. '
'Selamat mengerjakan 🙂.',
softWrap: true,
),
);
Dengan memberi nilai softWrap
= true, baris teks akan memenuhi lebar kolom sebelum membungkusnya pada batas kata.
Tambahkan widget variabel textSection
ke dalam body
seperti berikut:
Selesaikan langkah-langkah praktikum berikut ini dengan melanjutkan dari praktikum sebelumnya.
Anda dapat mencari gambar di internet yang ingin ditampilkan. Buatlah folder images
di root project layout_flutter. Masukkan file gambar tersebut ke folder images
, lalu set nama file tersebut ke file pubspec.yaml
seperti berikut:
Contoh nama file gambar di atas adalah lake.jpg
Tambahkan aset gambar ke dalam body
seperti berikut:
BoxFit.cover
memberi tahu kerangka kerja bahwa gambar harus sekecil mungkin tetapi menutupi seluruh kotak rendernya.
Pada langkah terakhir ini, atur semua elemen dalam ListView
, bukan Column, karena ListView
mendukung scroll yang dinamis saat aplikasi dijalankan pada perangkat yang resolusinya lebih kecil.
README.md
!Perpindahan halaman di Flutter, ditangani oleh Navigator dengan melibatkan konsep sebagai berikut:
MaterialPageRoute
.Sebuah Route
umumnya dimasukkan (push) atau diambil (pop) dari dan ke tumpukan Navigator
. Ketika sebuah halaman dilakukan operasi push, maka halaman tersebut akan diletakkan di atas halaman yang memanggilnya. Ilustrasi tersebut dapat anda lihat pada gambar berikut. Dan jika pop dipanggil (tombol back ditekan) maka aplikasi akan menampilkan halaman sebelumnya. Selain itu Flutter juga mendukung adanya penamaan Route yang didefinisikan di awal.
Selesaikan langkah-langkah praktikum berikut ini menggunakan editor Visual Studio Code (VS Code) atau Android Studio atau code editor lain kesukaan Anda. Materi ini dapat dimasukkan ke Laporan Praktikum folder Week atau Pertemuan 06.
Tampilan akhir yang akan Anda buat
Pada praktikum 5 ini anda akan belajar mengenai pembangunan aplikasi bergerak multi halaman. Aplikasi yang dikembangkan berupa kasus daftar barang belanja. Pada aplikasi ini anda akan belajar untuk berpindah halaman dan mengirimkan data ke halaman lainnya. Gambaran mockup hasil akhir aplikasi dapat anda lihat pada gambar di atas (mockup dibuat sederhana, sehingga Anda mempunyai banyak ruang untuk berkreasi). Desain aplikasi menampilkan sebuah ListView
widget yang datanya bersumber dari List
. Ketika item ditekan, data akan dikirimkan ke halaman berikutnya.
Sebelum melanjutkan praktikum, buatlah sebuah project baru Flutter dengan nama belanja dan susunan folder seperti pada gambar berikut. Penyusunan ini dimaksudkan untuk mengorganisasi kode dan widget yang lebih mudah.
Buatlah dua buah file dart dengan nama home_page.dart
dan item_page.dart
pada folder pages. Untuk masing-masing file, deklarasikan class HomePage
pada file home_page.dart
dan ItemPage
pada item_page.dart
. Turunkan class dari StatelessWidget
. Gambaran potongan kode dapat anda lihat sebagai berikut.
main.dart
Setelah kedua halaman telah dibuat dan didefinisikan, bukalah file main.dart
. Pada langkah ini anda akan mendefinisikan Route untuk kedua halaman tersebut. Definisi penamaan route harus bersifat unique. Halaman HomePage didefinisikan sebagai /. Dan halaman ItemPage didefinisikan sebagai /item. Untuk mendefinisikan halaman awal, anda dapat menggunakan named argument initialRoute
. Gambaran tahapan ini, dapat anda lihat pada potongan kode berikut.
Sebelum melakukan perpindahan halaman dari HomePage
ke ItemPage
, dibutuhkan proses pemodelan data. Pada desain mockup, dibutuhkan dua informasi yaitu nama dan harga. Untuk menangani hal ini, buatlah sebuah file dengan nama item.dart
dan letakkan pada folder models. Pada file ini didefinisikan pemodelan data yang dibutuhkan. Ilustrasi kode yang dibutuhkan, dapat anda lihat pada potongan kode berikut.
HomePage
Pada halaman HomePage
terdapat ListView
widget. Sumber data ListView
diambil dari model List dari object Item. Gambaran kode yang dibutuhkan untuk melakukan definisi model dapat anda lihat sebagai berikut.
Untuk menampilkan ListView
pada praktikum ini digunakan itemBuilder
. Data diambil dari definisi model yang telah dibuat sebelumnya. Untuk menunjukkan batas data satu dan berikutnya digunakan widget Card
. Kode yang telah umum pada bagian ini tidak ditampilkan. Gambaran kode yang dibutuhkan dapat anda lihat sebagai berikut.
Jalankan aplikasi pada emulator atau pada device anda.
ListView
Item pada ListView saat ini ketika ditekan masih belum memberikan aksi tertentu. Untuk menambahkan aksi pada ListView dapat digunakan widget InkWell
atau GestureDetector
. Perbedaan utamanya InkWell
merupakan material widget yang memberikan efek ketika ditekan. Sedangkan GestureDetector
bersifat umum dan bisa juga digunakan untuk gesture lain selain sentuhan. Pada praktikum ini akan digunakan widget InkWell
.
Untuk menambahkan sentuhan, letakkan cursor pada widget pembuka Card
. Kemudian gunakan shortcut quick fix dari VSCode (Ctrl + . pada Windows atau Cmd + . pada MacOS). Sorot menu wrap with widget...
Ubah nilai widget menjadi InkWell
serta tambahkan named argument onTap
yang berisi fungsi untuk berpindah ke halaman ItemPage
. Ilustrasi potongan kode dapat anda lihat pada potongan berikut.
Jalankan aplikasi kembali dan pastikan ListView dapat disentuh dan berpindah ke halaman berikutnya. Periksa kembali jika terdapat kesalahan.
Navigator
. Perbarui kode pada bagian Navigator
menjadi seperti berikut.Navigator.pushNamed(context, '/item', arguments: item);
ModalRoute
. Tambahkan kode berikut pada blok fungsi build dalam halaman ItemPage
. Setelah nilai didapatkan, anda dapat menggunakannya seperti penggunaan variabel pada umumnya. (https://docs.flutter.dev/cookbook/navigation/navigate-with-arguments)final itemArgs = ModalRoute.of(context)!.settings.arguments as Item;
GridView
seperti di aplikasi marketplace pada umumnya.Hero widget
pada aplikasi belanja Anda dengan mempelajari dari sumber ini: https://docs.flutter.dev/cookbook/navigation/hero-animations README.md.
Kumpulkan link commit repository GitHub Anda kepada dosen yang telah disepakati!Selamat Anda telah menyelesaikan Codelab ini. Anda telah mempelajari Layout, Navigasi, dan rute di Flutter.
Pada codelab berikutnya, Anda akan mempelajari tentang manajemen plugin di Flutter.
Silakan cek beberapa sumber belajar lainnya...