Repository ini adalah kumpulan latihan bertahap untuk belajar Dart dan Flutter dari dasar sampai studi kasus. Materinya disusun seperti syllabus beginner track: mulai dari tipe data, widget sederhana, layout, navigation, HTTP request, package Flutter, sampai GetX, Get CLI, state management, route management, dependency injection, local storage, theme, dan studi kasus API ongkir.
-
Dart Fundamental
Belajar tipe data, list, map, function, loop, conditional, null safety, class, object, dan constructor. -
Flutter Basic UI
MengenalMaterialApp,Scaffold,AppBar, widget sederhana, layout, extract widget, reusable widget, dialog, snackbar, text field, tab, dropdown, bottom navigation, bottom sheet, drawer, dan navigation. -
Mini UI Practice
Latihan membuat tampilan sederhana seperti profile Instagram dan basic UI challenge. -
HTTP & Async Data
BelajarGET,POST,PUT,PATCH,DELETE,FutureBuilder, parsing JSON, dan menampilkan data API ke UI. -
Flutter Packages
Mengenal package sepertifaker,intl, bottom bar,avatar_glow, intro screen, dropdown search, daftar wilayah Indonesia, dan app launcher icon. -
GetX Track
BelajarGetMaterialApp, snackbar/dialog/bottomsheet GetX, simple state management, reactive variable, workers, dependency management, route management, named route, bindings,GetStorage, dan struktur project Get CLI. -
Study Case
Project RajaOngkir dengan model, provider, controller, dropdown dependent, loading state, reactive list, dan hasil cek ongkir.
| Folder | Materi Latihan |
|---|---|
00_belajar_dart |
Fundamental Dart: variable, tipe data, list, map, function, loop, conditional, null safety, class, object, constructor. |
01_widget_sederhana |
Struktur awal Flutter: runApp, MaterialApp, Scaffold, AppBar, Container, ElevatedButton, image provider. |
02_widget_layout |
Layout dasar Flutter dan penyusunan widget di layar. |
03_extract_widget |
Memecah UI menjadi widget sendiri agar kode lebih rapi dan reusable. |
04_widget_builder |
Membuat widget berulang dengan pola builder/reusable component. |
05_latihan_basic_1 |
Kumpulan soal latihan basic Flutter untuk memperkuat widget dan layout. |
06_stateless_vs_statefull |
Perbedaan StatelessWidget dan StatefulWidget, kapan UI perlu state. |
07_dialog |
Dialog bawaan Flutter untuk konfirmasi atau pesan tambahan. |
08_snackbar |
Snackbar bawaan Flutter untuk feedback singkat ke user. |
09_textfield |
Input user dengan TextField dan controller. |
10_tabbar |
Navigasi tab dengan TabBar dan TabBarView. |
11_dropdown |
Input pilihan memakai dropdown. |
12_bottom_navigation_bar |
Navigasi antar menu utama dengan bottom navigation. |
13_bottom_sheet |
Menampilkan panel dari bawah layar. |
14_drawer |
Side navigation memakai drawer. |
15_navigation |
Navigasi antar halaman: home, product, profile. |
16_latihan_ui_instagram |
Latihan slicing UI profile Instagram dengan widget terpisah. |
17_http_get |
Request API metode GET, parsing JSON, dan update UI dengan setState. |
18_http_post |
Mengirim data ke API dengan metode POST. |
19_http_put_or_patch |
Update data API memakai PUT atau PATCH. |
20_http_delete |
Menghapus data via API dengan metode DELETE. |
21_future_builder |
Menampilkan async data memakai FutureBuilder. |
22_latihan_http_covid_app |
Mini app data Covid: model, page, widget info card, dan HTTP. |
23_faker |
Generate dummy data memakai package faker. |
24_date_format |
Format tanggal dengan package intl. |
25_package_bottom_bar |
Eksperimen package bottom bar untuk navigasi. |
26_avatar_glow |
Efek avatar glow dengan package avatar_glow. |
27_package_intro_screen |
Halaman onboarding/intro screen. |
28_package_dropdown_search |
Dropdown dengan fitur search. |
29_daftar_wilayah_indo |
Mengambil dan menampilkan data wilayah Indonesia dari API. |
30_change_app_icon |
Mengubah launcher icon aplikasi dengan flutter_launcher_icons. |
31_belajar_getx |
Pengenalan GetX dan GetMaterialApp. |
32_snackbar_getx |
Snackbar versi GetX dengan API yang lebih ringkas. |
33_dialog_getx |
Dialog versi GetX. |
34_bottomsheet_getx |
Bottom sheet versi GetX. |
35_state_management_getx |
Simple state management GetX dengan GetBuilder dan update(). |
36_reactive_variables |
Reactive state GetX dengan .obs, RxInt, RxString, RxBool, RxList, dan Obx. |
37_workers_getx |
Worker GetX: ever, once, debounce, dan interval. |
38_dependency_management_getx |
Dependency injection GetX: Get.put, Get.lazyPut, dan Get.find. |
39_route_management_getx |
Route management GetX tanpa context. |
40_routename_getx |
Named route GetX dengan daftar route. |
41_bindings_builder |
Binding GetX untuk mendaftarkan controller sebelum route dibuka. |
42_getstorage |
Local storage sederhana dengan GetStorage, cocok untuk remember login/cache kecil. |
43_get_cli |
Struktur project Get CLI: modules, bindings, controllers, views, routes. |
44_latihan_get_cli |
Latihan Get CLI dengan model dan provider. |
45_studycase_rajaongkir |
Studi kasus cek ongkir: model, provider, controller, dropdown provinsi/kota, kurir, berat, dan hasil cost. |
46_theme_and_contscolor |
Theme management dan constant color di project GetX/Get CLI. |
Masuk ke salah satu folder project Flutter, lalu jalankan:
flutter pub get
flutter runContoh:
cd 35_state_management_getx
flutter pub get
flutter runUntuk materi Dart murni:
cd 00_belajar_dart
dart section1.dartclass Pakaian {
String? jenis;
String? warna;
Pakaian({this.jenis, this.warna});
}
void main() {
final pakaian = Pakaian(jenis: "baju", warna: "merah");
print("Ini adalah ${pakaian.jenis} berwarna ${pakaian.warna}");
}void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
home: HomePage(),
);
}
}final response = await http.get(
Uri.parse("https://jsonplaceholder.typicode.com/todos/3"),
);
if (response.statusCode == 200) {
final data = jsonDecode(response.body);
setState(() {
title = data["title"];
});
}FutureBuilder<List<dynamic>>(
future: getData(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(child: CircularProgressIndicator());
}
if (snapshot.hasError) {
return Center(child: Text("Error: ${snapshot.error}"));
}
final data = snapshot.data ?? [];
return ListView.builder(
itemCount: data.length,
itemBuilder: (context, index) => ListTile(
title: Text(data[index]["title"]),
),
);
},
);class HomeController extends GetxController {
var angka = 0;
void tambah() {
angka++;
update();
}
}GetBuilder<HomeController>(
init: HomeController(),
builder: (controller) {
return Text("${controller.angka}");
},
);class HomeController extends GetxController {
RxInt counter = 0.obs;
void increment() {
counter++;
}
}Obx(() => Text("${controller.counter.value}"));@override
void onInit() {
ever(dataPantau, (_) => print("Data berubah"));
debounce(
dataPantau,
(_) => print("Jalan setelah user berhenti mengubah data"),
time: const Duration(seconds: 2),
);
super.onInit();
}class CounterBinding extends Bindings {
@override
void dependencies() {
Get.lazyPut(() => CounterController());
}
}GetPage(
name: "/counter",
page: () => CounterPage(),
binding: CounterBinding(),
);void main() async {
await GetStorage.init();
runApp(const MyApp());
}
final box = GetStorage();
box.write("dataRemember", {
"email": emailC.text,
"password": passwordC.text,
});GetMaterialApp(
debugShowCheckedModeBanner: false,
initialRoute: AppPages.INITIAL,
getPages: AppPages.routes,
);Struktur yang dipakai Get CLI:
lib/
app/
data/
models/
providers/
modules/
home/
bindings/
controllers/
views/
routes/
app_pages.dart
app_routes.dart
main.dart
class HomeController extends GetxController {
final ProvinceProvider provinceProvider = Get.find();
final provinceList = <Province>[].obs;
final originCityList = <City>[].obs;
final selectedOriginProvince = Rxn<Province>();
final selectedOriginCity = Rxn<City>();
final isLoadingProvince = false.obs;
@override
void onInit() {
super.onInit();
loadProvince();
}
Future<void> loadProvince() async {
try {
isLoadingProvince.value = true;
final result = await provinceProvider.getProvinces();
provinceList.assignAll(result);
} finally {
isLoadingProvince.value = false;
}
}
}| Package | Dipakai Untuk |
|---|---|
http |
Request API dan komunikasi data JSON. |
get |
State management, navigation, snackbar/dialog/bottomsheet, dependency injection, binding. |
get_storage |
Menyimpan data kecil di local storage. |
faker |
Membuat dummy data untuk latihan UI/list. |
intl |
Format tanggal dan data lokal. |
avatar_glow |
Efek animasi glow pada avatar. |
flutter_launcher_icons |
Generate launcher icon aplikasi. |
- Kerjakan folder secara berurutan dari
00_belajar_dartsampai46_theme_and_contscolor. - Kalau masih baru di Flutter, fokus dulu ke widget, layout, dan navigation sebelum masuk GetX.
- Untuk GetX, pahami urutan ini:
GetMaterialApp-> controller ->GetBuilder/Obx-> route -> binding -> storage -> Get CLI. - Untuk project API, biasakan memisahkan
model,provider/service,controller, danview.
Setelah menyelesaikan semua folder, kamu diharapkan bisa:
- Menulis basic Dart dengan null safety.
- Membuat UI Flutter dari widget kecil sampai layout halaman.
- Mengelola input, dialog, snackbar, drawer, tab, dan navigation.
- Mengambil data API dan menampilkan loading/error/success state.
- Memakai package Flutter sesuai kebutuhan.
- Mengelola state dengan GetX simple dan reactive.
- Menyusun project Get CLI dengan modules, bindings, controllers, views, routes, model, dan provider.
- Membuat mini app berbasis API seperti cek ongkir RajaOngkir.