1 Pengertian Widget
Widget di Flutter adalah elemen dasar yang digunakan untuk membangun antarmuka pengguna
(UI) pada aplikasi Flutter. Setiap elemen pada tampilan aplikasi, seperti teks, tombol, atau gambar,
adalah contoh dari sebuah widget. Widget adalah komponen yang dapat dikombinasikan dan
disusun untuk membentuk tampilan dan fungsi aplikasi secara keseluruhan.
Dalam Flutter, widget adalah kelas yang di-extend dari kelas dasar Widget. Ada dua jenis utama
widget yang digunakan dalam Flutter:
2.1 StatelessWidget
Stateless Widget: Merupakan widget yang tidak memiliki state atau kondisi internal yang
berubah. Stateless widget dibangun hanya berdasarkan konfigurasi yang diberikan oleh parent
widget. Contohnya adalah Text dan Icon.
import 'package:flutter/material.dart';
import 'package:flutter/material.dart';
@override
_MyAppState createState() => _MyAppState();
}
void incrementCounter() {
setState(() {
counter++;
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Contoh Stateful Widget')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text('Tombol ditekan sebanyak:'),
Text('$counter', style: TextStyle(fontSize: 24)),
ElevatedButton(
onPressed: incrementCounter,
child: Text('Tambahkan'),
),
],
),
),
),
);
}
}
Dalam pengembangan aplikasi Flutter, para pengembang biasanya akan membuat struktur
widget yang saling berhubungan, yang disebut sebagai "widget tree" (pohon widget). Widget tree
memungkinkan pengembang untuk menggabungkan dan mengelola widget yang berbeda untuk
menciptakan antarmuka pengguna yang kompleks dan interaktif.
Untuk membuat Text Widget, kita perlu menyediakan nilai teks yang akan ditampilkan di
dalamnya. Selain itu, kita juga dapat mengatur properti seperti style, textAlign, dan overflow untuk
mengatur format dan tampilan dari teks yang ditampilkan.
Berikut adalah contoh kode sederhana untuk membuat Text Widget di Flutter:
import 'package:flutter/material.dart';
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('Contoh Text Widget')),
body: const Center(
child: Text(
'Halo, Flutter!',
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
textAlign: TextAlign.center,
),
),
),
);
}
}
Pada contoh di atas, kita membuat sebuah Text Widget dengan nilai teks "Halo, Flutter!". Properti
style digunakan untuk mengatur ukuran dan tebal huruf pada teks, sedangkan properti textAlign
digunakan untuk mengatur posisi teks dalam widget. Widget ini akan ditampilkan di tengah layar
karena dibungkus oleh Center Widget.
ruang di dalam antarmuka pengguna aplikasi. Widget ini berfungsi sebagai wadah kosong atau
kotak yang dapat diisi dengan widget lain atau ditambahkan properti untuk mengubah tampilan
dan fungsi kotak tersebut.
Untuk membuat Container Widget, kita perlu menyediakan anak widget yang akan ditampilkan di
dalamnya. Selain itu, kita juga dapat mengatur properti seperti padding, margin, dan decoration
untuk mengatur ukuran, jarak, dan gaya dari kotak tersebut.
Berikut adalah contoh kode sederhana untuk membuat Container Widget di Flutter:
import 'package:flutter/material.dart';
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('Contoh Container Widget')),
body: Center(
child: Container(
width: 200,
height: 200,
margin: const EdgeInsets.all(20),
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.5),
spreadRadius: 5,
blurRadius: 7,
offset: const Offset(0, 3),
),
],
),
child: const Text(
'Ini adalah Container Widget',
style: TextStyle(fontSize: 20, color: Colors.white),
),
),
),
),
);
}
}
Pada contoh di atas, kita membuat sebuah
Container Widget dengan anak widget berupa Text
kolom vertikal. Widget ini memungkinkan para pengembang untuk menempatkan beberapa
widget dalam kolom tunggal yang disusun secara vertikal.
Untuk membuat Column Widget, kita perlu menyediakan widget anak yang akan ditampilkan di
dalamnya. Kita juga dapat mengatur properti seperti mainAxisAlignment dan crossAxisAlignment
untuk mengatur cara tata letak dari widget anak dalam kolom.
Berikut adalah contoh kode sederhana untuk membuat Column Widget di Flutter:
import 'package:flutter/material.dart';
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('Contoh Column Widget')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: const <Widget>[
Text('Item 1'),
Text('Item 2'),
Text('Item 3'),
],
),
),
),
);
}
}
Pada contoh di atas, kita membuat sebuah Column
Widget dengan tiga Text Widget sebagai anaknya.
dalam antarmuka pengguna aplikasi. Widget ini memungkinkan para pengembang untuk
menampilkan gambar dari berbagai sumber, seperti file lokal, jaringan, atau bahkan memori.
Untuk membuat Image Widget, kita perlu menyediakan sumber gambar yang akan ditampilkan di
dalamnya. Kita juga dapat mengatur properti seperti width, height, dan fit untuk mengatur ukuran
dan penampilan dari gambar yang ditampilkan.
Berikut adalah contoh kode sederhana untuk membuat Image Widget di Flutter:
import 'package:flutter/material.dart';
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('Contoh Image Widget')),
body: Center(
child: Image.network(
'https://picsum.photos/250?image=9',
width: 200,
height: 200,
fit: BoxFit.cover,
),
),
),
);
}
}
Pada contoh di atas, kita membuat sebuah Image
Widget dengan sumber gambar dari jaringan
antarmuka pengguna aplikasi. Widget ini memungkinkan para pengembang untuk menampilkan
berbagai ikon bawaan yang disediakan oleh Flutter atau ikon kustom yang dibuat sendiri.
Untuk membuat Icon Widget, kita perlu menyediakan jenis ikon yang akan ditampilkan dengan
menggunakan properti Icons. Kita juga dapat mengatur properti seperti size dan color untuk
mengatur ukuran dan warna dari ikon yang ditampilkan.
Berikut adalah contoh kode sederhana untuk membuat Icon Widget di Flutter:
import 'package:flutter/material.dart';
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('Contoh Icon Widget')),
body: const Center(
child: Icon(
Icons.favorite,
size: 100,
color: Colors.red,
),
),
),
);
}
}
Pada contoh di atas, kita membuat sebuah Icon
Widget dengan menggunakan properti Icons.favorite.
dapat dipicu oleh pengguna. Widget ini memungkinkan para pengembang untuk membuat
tombol dengan berbagai gaya dan perilaku, seperti tombol teks, tombol gambar, tombol ikon, dan
sebagainya.
Untuk membuat Button Widget, kita perlu menyediakan anak widget yang akan ditampilkan di
dalamnya, seperti Text, Icon, atau Image. Kita juga dapat mengatur properti seperti onPressed,
color, dan textColor untuk mengatur perilaku dan tampilan dari tombol yang dibuat.
Berikut adalah contoh kode sederhana untuk membuat ElevatedButton dan TextButton di Flutter:
import 'package:flutter/material.dart';
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('Contoh Button Widget')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ElevatedButton(
style: ElevatedButton.styleFrom(
foregroundColor: Colors.white,
textStyle: const TextStyle(
color: Colors.white,
fontSize: 12,
fontStyle: FontStyle.normal
),
),
onPressed: () {
_showDialog(context);
},
child: const Text('Elevated Button'),
),
const SizedBox(height: 22),
TextButton(
style: TextButton.styleFrom(
foregroundColor: Colors.blue, // foreground
),
onPressed: () {
_showDialog(context);
},
child: const Text('TextButton with custom foreground'),
),
],
),
),
),
);
}
}
Pada contoh di atas, kita membuat sebuah
ElevatedButton dan TextButton. Properti onPressed
digunakan untuk menentukan fungsi yang akan
dipanggil ketika tombol ditekan, sedangkan
properti color dan textColor digunakan untuk
mengatur warna dan gaya dari tombol. Kita juga
dapat mengatur properti padding untuk mengatur
jarak antara teks dan batas tombol. Ketika tombol
ditekan, kita menampilkan dialog sederhana yang
memberi tahu pengguna bahwa tombol telah
ditekan.
3.7 Stack Widget
Stack Widget di Flutter adalah widget yang digunakan untuk menumpuk widget lain dalam
antarmuka pengguna aplikasi. Widget ini memungkinkan para pengembang untuk menempatkan
beberapa widget dalam lapisan tunggal yang tumpang tindih.
Dalam Stack Widget, widget anak ditempatkan pada lapisan yang berbeda, yang dapat dikontrol
dengan menggunakan properti Positioned pada setiap widget anak. Positioned digunakan untuk
mengatur posisi, ukuran, dan tampilan dari widget anak dalam Stack Widget.
Berikut adalah contoh kode sederhana untuk membuat Stack Widget di Flutter:
import 'package:flutter/material.dart';
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('Contoh Stack Widget')),
body: Stack(
children: <Widget>[
Container(
width: double.infinity,
height: double.infinity,
color: Colors.yellow,
),
Positioned(
top: 50,
left: 50,
child: Container(
width: 100,
height: 100,
color: Colors.red,
),
),
Positioned(
bottom: 50,
right: 50,
child: Container(
width: 100,
height: 100,
color: Colors.blue,
),
),
],
),
),
);
}
}
Flutter menyediakan beberapa widget navigasi yang berguna, seperti Navigator, MaterialApp, dan
Scaffold. Kita dapat menggunakan widget ini untuk membuat routing dan navigasi yang responsif
Berikut adalah contoh kode sederhana untuk membuat navigasi dan routing di Flutter:
import 'package:flutter/material.dart';
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Contoh Navigasi dan Routing',
initialRoute: '/',
routes: {
'/': (context) => HomePage(),
'/about': (context) => AboutPage(),
},
);
}
}
Pada contoh di atas, kita membuat dua halaman dengan menggunakan HomePage dan AboutPage.
Kita menggunakan widget MaterialApp untuk menentukan initialRoute sebagai halaman utama dan
menambahkan dua rute dengan nama / dan /about dalam routes. Widget ElevatedButton pada
HomePage digunakan untuk menavigasi ke halaman AboutPage dengan memanggil fungsi
Dalam contoh di atas, kita menggunakan MaterialApp, Scaffold, AppBar, dan ElevatedButton untuk
membuat navigasi dan routing yang sederhana dan mudah dipahami oleh pengguna. Kita dapat
memodifikasi contoh di atas untuk membuat navigasi dan routing yang lebih kompleks sesuai
dengan kebutuhan aplikasi kita.
4.2 MaterialPageRoute
MaterialPageRoute di Flutter adalah widget yang digunakan untuk membuat rute navigasi dengan
transisi animasi standar yang terdapat di Material Design. Widget ini memungkinkan para
pengembang untuk membuat tampilan transisi halaman yang menarik dengan mudah.
MaterialPageRoute menyediakan beberapa properti yang dapat dikonfigurasi, seperti builder,
settings, dan fullscreenDialog, yang dapat digunakan untuk menentukan tampilan dan perilaku dari
import 'package:flutter/material.dart';
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Contoh MaterialPageRoute',
home: HomePage(),
);
}
}
Pada contoh di atas, kita menggunakan MaterialPageRoute untuk menavigasi dari HomePage ke
AboutPage. Kita membuat rute baru dengan menggunakan MaterialPageRoute(builder: (context) =>
AboutPage()). Ketika pengguna menekan tombol pada HomePage, aplikasi akan menampilkan
tampilan transisi halaman dari HomePage ke AboutPage. Ketika pengguna menekan tombol pada
AboutPage, aplikasi akan kembali ke halaman sebelumnya.
Dalam contoh di atas, kita menggunakan MaterialPageRoute untuk membuat tampilan transisi
halaman yang standar. Kita dapat memodifikasi contoh di atas untuk membuat tampilan transisi
halaman yang lebih kompleks sesuai dengan kebutuhan aplikasi kita.
Widget ini memungkinkan para pengembang untuk membuat stack navigasi yang dapat
digunakan untuk menampilkan dan menghapus halaman dalam aplikasi.
Navigator Widget memungkinkan kita untuk menambahkan halaman baru ke dalam stack navigasi
dengan menggunakan metode push(), menghapus halaman dari stack navigasi dengan
menggunakan metode pop(), atau mengganti halaman aktif dengan menggunakan metode
pushReplacement().
Widget Navigator biasanya ditempatkan pada widget paling atas dalam hirarki widget aplikasi.
Berikut adalah contoh kode sederhana untuk menggunakan Navigator Widget di Flutter:
import 'package:flutter/material.dart';
MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Contoh Navigator Widget',
navigatorKey: navigatorKey,
home: HomePage(navigatorKey),
);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Home')),
body: Center(
child: ElevatedButton(
child: const Text('Tentang'),
onPressed: () {
navigatorKey.currentState?.push(
MaterialPageRoute(builder: (context) => AboutPage()),
);
},
),
),
);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Tentang')),
body: Center(
child: ElevatedButton(
child: const Text('Kembali ke Beranda'),
onPressed: () {
Navigator.pop(context);
},
),
),
);
}
}
Pada contoh di atas, kita menggunakan widget Navigator dengan membuat objek
GlobalKey<NavigatorState> dan menginisialisasinya pada MaterialApp dengan navigatorKey:
navigatorKey. Kita menggunakan push() dan pop() pada objek currentState dari navigatorKey untuk
5 State Management
Ada beberapa cara untuk melakukan state management di Flutter, seperti menggunakan widget
stateful, InheritedWidget, BLoC, MobX, atau Provider. Setiap pendekatan memiliki kelebihan dan
kelemahan tersendiri, tergantung pada kompleksitas aplikasi yang dibangun.
Sebagai contoh, berikut adalah contoh sederhana untuk menggunakan widget stateful untuk
melakukan state management di Flutter:
import 'package:flutter/material.dart';
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: 'Contoh State Management',
home: CounterWidget(),
);
}
}
@override
_CounterWidgetState createState() => _CounterWidgetState();
}
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Stateful Widget'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'Anda telah menekan tombol sebanyak:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headlineMedium,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Tambah',
child: const Icon(Icons.add),
),
);
}
}
Pada contoh di atas, kita menggunakan widget stateful CounterWidget untuk mengelola state
aplikasi. Kita mendeklarasikan variabel _counter yang bertipe int untuk menyimpan nilai saat ini,
dan menggunakan metode _incrementCounter() untuk meningkatkan nilai _counter setiap kali
tombol ditap. Kita memperbarui tampilan aplikasi menggunakan metode setState() yang
membangkitkan ulang widget ketika data berubah.
Contoh di atas adalah salah satu cara untuk melakukan state management di Flutter dengan
menggunakan widget stateful. Namun, metode ini mungkin tidak efektif untuk aplikasi yang lebih
kompleks, seperti aplikasi yang membutuhkan data yang bersifat global dan perlu diakses oleh
banyak widget.
5.2 Provider
Provider adalah paket Flutter yang menyediakan solusi state management sederhana, cepat, dan
efektif untuk membagikan dan mengakses data antar widget pada aplikasi Flutter. Provider
memungkinkan para pengembang untuk memisahkan logika aplikasi dari tampilan aplikasi dan
memudahkan pengelolaan state secara efisien.
Dalam Provider, data disimpan dalam objek Model, dan Model tersebut dapat diakses dan
digunakan oleh widget yang membutuhkan data tersebut. Provider menggunakan konsep
dependency injection untuk memberikan akses ke Model tersebut pada widget tanpa perlu
membuat banyak boilerplate code.
import 'package:flutter/material.dart';
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Contoh MaterialPageRoute',
home: HomePage(),
);
}
}
Pada contoh di atas, kita menggunakan Provider untuk mengelola state aplikasi dengan membuat
objek CounterModel yang memiliki variabel _counter dan metode incrementCounter() untuk
mengubah nilai _counter. Objek CounterModel kemudian dipakai pada widget CounterWidget
dengan menggunakan Provider.of untuk mengakses data yang disimpan dalam objek CounterModel.
Dengan menggunakan Provider, kita dapat memisahkan logika aplikasi dari tampilan dan
memudahkan pengelolaan state secara efisien tanpa perlu membuat banyak boilerplate code.
Provider adalah solusi state management yang sederhana, cepat, dan efektif untuk membagikan
Flutter BLOC adalah state management system pada Flutter yang dibuat dan dikembangkan oleh
Felix Angelov. BLOC pattern membantu pengelolaan state dan membuat akses ke data
tersentralisasi.
Seperti namanya, BLOC menggunakan pendekatan arsitektur business logic dan persentation
(view) yang dibuat secara terpisah. Tujuan dari BLOC sendiri adalah membuat kode program
aplikasi kamu menjadi lebih mudah dibaca, terstruktur, maintainable, dan testable.
Fitur utama yang menjadi core concept dalam package BLOC ada 2, yaitu:
Bloc
Cubit
Kedua fitur diatas memiliki kegunaan masing-masing yang dapat digunakan sesuai kondisi dan
kebutuhan. Cubit dinilai memiliki fungsi untuk mengelola state yang lebih sederhana dibanding
BLOC.
Karena, di dalam Cubit hanya ada interaksi antara business logic dan state saja, tanpa ada event
spesifik yang didefinisikan. Berbeda dengan BLOC yang memiliki struktur lengkap mulai dari
business logic, event, dan state.