Skip to content

Platform-Based Programming (CSGE602022) - Organized by the Faculty of Computer Science Universitas Indonesia, Odd Semester 2022/2023

Notifications You must be signed in to change notification settings

eugeniusms/pbp-flutter-lab

Repository files navigation

counter_7

Stateless vs Stateful Widget

  1. Stateless Widget Adalah sebuah widget yang bersifat statis (tidak berubah). Stateless Widget bekerja dengan konsep Constructor -> Build. Konsep ini berarti widget langsung mengarahkan object untuk Build tanpa memiliki perantara untuk pengolahan variabel di dalam prosesnya.
  2. Stateful Widget Adalah sebuah widget yang bersifat dinamis. Widget dapat merubah tampilan sesuai respon dari tindakan yang dilakukan oleh user maupun perubahan berdasarkan operasi yang ada di dalam widget itu sendiri. Stateful Widget bekerja dengan konsep Constructor -> Internal State -> Build, artinya terdapat perantara berupa sebuah data maupun variabel yang disebut sebagai state (bersifat dinamis). State tersebut akan diolah dan disesuaikan kemudian ditampilkan saat Build.
Stateless Widget Stateful Widget
Bersifat statis Bersifat dinamis
Tampilan tetap (tidak berubah) Tampilan menyesuaikan interaksi user
Alur: Contructor -> Build Alur: Constructor -> Internal State -> Build
Lebih ringan dirender Memerlukan waktu reload render
Cocok untuk widget tanpa perubahan data di dalamnya Diperlukan untuk menyusun widget dengan pengolahan data yang interaktif

counter_7's Widgets

Widget Fungsi
CounterSeven Inisiasi aplikasi
CounterPage Menampilkan counter dan button serta logicnya
MaterialApp Inisiasi title, theme, dan mengatur home dari aplikasi
ThemeData Mengatur tema yang digunakan
Scaffold Mengatur layout dari widget yang ada di dalamnya
AppBar Menambahkan bar aplikasi yang berisi title dengan align left
Text Berisi sebuah Text dengan properti di dalamnya
Center Mengatur layout widget di dalamnya agar centered
Column Mengatur layout widget di dalamnya agar turun ke bawah (tidak inline-flex)
TextStyle Mengatur style dari sebuah text
Container Menampung beberapa widget di dalamnya
Row Mengatur layout widget di dalamnya agar menyamping (inline-flex)
FloatingActionButton Membuat tombol yang dapat dimodifikasi event di dalamnya
Icon Menampilkan icon yang dibutuhkan sesuai propertinya

Const vs Final

const final
Const dapat digunakan untuk deklarasi variabel immutable yang nilainya bersifat konstan. Setiap kali perlakuan render tetap dapat terinisiasi ulang sesuai nilainya sehingga lebih fleksibel pada keadaan yang memerlukan render data. Akan tetapi, tetap saja const tidak dapat diubah saat berada di runtime satu kali cycle program. Final berarti single-assignment, sebuah final variabel perlu diinisiasi, sekalinya diinisiasi, nilai variabel tidak dapat diubah. Final dapat dimanfaatkan untuk meletakkan data-data yang tidak akan berubah sekalipun ada rendering (reload)

Project Implementation

  1. Membuat aplikasi Flutter bernama counter_7 dengan command flutter create counter_7
  2. Menambahkan modules dari import flutter package dan fungsi main() yang dieksekusi pertama kali oleh Flutter pada main.dart
  3. Mengarahkan runApp() menuju aplikasi terkait 'CounterSeven'
  4. Menyusun CounterSeven sebagai StatelessWidget dan menambahkan MaterialApp widget untuk menginisiasikan hal-hal penting yang ditampilkan dalam aplikasi
  5. Mengarahkan home: menuju halaman CounterPage yang sudah diimport dari directory /pages/CounterPage.dart
  6. Menyusun CounterPage sebagai StatefulWidget dengan beberapa atributnya seperti judul dan key. Kemudian menambahkan state _CounterState() ke dalam widget untuk menyimpan internal state dari nilai _counter
  7. Menyusun _CounterState sebagai widget yang digunakan untuk menampilkan hasil counter
  8. Menginisiasikan _counter = 0 untuk state awal, lalu menambahkan dua fungsi _decrementCounter() dan _incrementCounter() yang digunakan untuk mengeset state menuju nilai yang diinginkan, yaitu -1 untuk _decrementCounter() dan +1 untuk _incrementCounter()
  9. Menyusun widget dengan Scaffold yang digunakan untuk menyimpan beberapa widget lain di dalamnya
  10. Menambahkan title pada Widget AppBar dan mengatur alignment dari title tersebut
  11. Menambahkan body dengan Widget Center untuk meletakkan child widget ke tengah
  12. Children widget pada body berisi Widget Text yang digunakan untuk menampilkan "GANJIL" vs "GENAP" sesuai kondisi nilai _counter saat ini beserta dengan TextStylenya. Jika _counter % 2 == 0 maka tampilkan blok "GENAP", sebaliknya tampilkan blok "GANJIL"
  13. Menambahkan dua button yaitu decrement & increment button menggunakan Widget FloatingActionButton yang disimpan dalam Widget Row (inline-flex posisi dari buttonya) di dalam Container.
  14. Mengarahkan atribut onPressed: pada button ke fungsi yang sesuai setStatenya, decrement button ke _decrementCounter dan increment button ke _incrementButton
  15. Menambahkan ikon ke button sesuai dengan permintaan soal, ikon negatif (Icons.remove) dan ikon plus (Icons.add)
  16. BONUS Menambahkan alur logika dari button decrement. Jika _counter > 0 maka tampilkan FloatingActionButton decrement, jika tidak maka tampilkan SizedBox() (widget kosong) untuk menghilangkan button saat nilai _counter <= 0

Tugas 8

Navigator.push vs Navigator.pushReplacement

  1. Navigator.pushReplacement
    Navigator ini akan menimpa halaman sekarang dengan halaman baru
  2. Navigator.push
    Navigator ini akan menambahkan rute lain ke atas tumpukan screen stack saat ini

Tugas 8's Widgets

Widget Fungsi
Drawer Membuat drawer navigator
ListTile Membuat list beberapa tile
MaterialPageRoute Mengarahkan routing ke halaman (widget) tertentu
FormBudgetPage Widget buatan sendiri untuk menampilkan halaman form
OutlineInputBorder Menambahkan border pada input
InputDecoration Menambahkan dekorasi input
ButtonStyle Menambahkan style button
SnackBar Menampilkan SnackBar
SingleChildScrollView Menyusun scroll type dari suatu body
Card Membuat card
TextFormField Membuat input field
DropdownButtonFormField Membuat dropdown sesuai validasi input
Spacer Membuat space fleksibel

Tugas 8's Events

Event Penjelasan
onPressed Event yang terjadi ketika user telah selesai menekan
onTap Event yang terjadi ketika sesaat setelah klik
onChanged Event yang terjadi ketika ada perubahan

Cara Kerja Navigator

Navigator bekerja selayaknya sebuah stack yang memiliki paradigma LIFO yaitu Last In First Out. Stack ini diterapkan pada layar untuk menampilkan layar dengan cara "PUSH" dan layar yang ditampilkan tersebut merupakan "TOP OF STACK", sedangkan layar sebelumnya berada di bawah dari "TOP OF STACK" dan seterusnya selama proses "PUSH" dan "POP" terjadi.

Project Implementation

  1. Menambahkan Drawer menu pada app counter_7
  2. Drawer disusun dengan memiliki 3 menu yaitu CounterPage, FormBudgetPage, dan ShowBudgetPage
  3. Membuat 2 file yang belum ada di dalam Drawer yaitu FormBudgetPage dan ShowBudgetPage
  4. Menyusun halaman FormBudgetPage
  5. Menambahkan input dengan tipe data String bernama judul
  6. Menambahkan input dengan tipe data integer bernama nominal
  7. Menambahkan elemen dropdown untuk menyeleksi "Pengeluaran/Pemasukan"
  8. Menambahkan button untuk menyimpan budget
  9. BONUS Menambahkan date picker
  10. Menambahkan toast saat tombol simpan diklik
  11. Menyusun halaman ShowBudgetPage
  12. BONUS Refactoring widget
  13. Widget Budget masuk ke dalam components untuk menyimpan Budget dan sebagai kerangkanya
  14. Mengambil data dari Budget ke dalam ShowBudgetPage
  15. Menyusun card dan style untuk membedakan pengeluaran dan pemasukan

Mario's References

Tugas 9

Apakah bisa kita melakukan pengambilan data JSON tanpa membuat model terlebih dahulu? Jika iya, apakah hal tersebut lebih baik daripada membuat model sebelum melakukan pengambilan data JSON?

Pengambilan data JSON tanpa membuat model terlebih dahulu dapat dilakukan, nantinya data masih dalam wujud jsonDecode var data = jsonDecode(utf8.decode(response.bodyBytes));. Namun, hal ini tidak lebih baik dibanding membuat model terlebih dahulu sebelum pengambilan data JSON karena data tidak langsung diinisiasi menjadi suatu object sesuai class modelnya.

Tugas 9's Widgets

Widget Fungsi
MyWatchlistPage Membuat halaman utama dari watchlist
SingleWatchlistPage Membuat halaman detail dari suatu watchlist
FutureBuilder Merupakan widget yang digunakan untuk melakukan proses asinkron
Checkbox Menampilkan Checkbox yang bisa diklik
MaterialPageRoute Mengarahkan routing ke halaman (widget) tertentu
Drawer Membuat drawer navigator
ListTile Membuat list beberapa tile
Scaffold Mengatur layout dari widget yang ada di dalamnya
AppBar Menambahkan bar aplikasi yang berisi title dengan align left
Text Berisi sebuah Text dengan properti di dalamnya
Center Mengatur layout widget di dalamnya agar centered
Column Mengatur layout widget di dalamnya agar turun ke bawah (tidak inline-flex)
TextStyle Mengatur style dari sebuah text
Container Menampung beberapa widget di dalamnya

Mekanisme Pengambilan Data dari JSON ke Flutter

  1. JSON ditampilkan di halaman asal proyek MyWatchlist di https://pbp-assignment-eugeniusms.herokuapp.com/mywatchlist/json/
  2. JSON difetch ke dalam fetch.dart sesuai urlnya dengan header "Access-Control-Allow-Origin": "*", "Content-Type": "application/json"
  3. JSON yang telah difetch akan disesuaikan bodynya menuju model Watchlist sesuai dengan properti-properti
  4. Data list dalam model Watchlist dipanggil dalam MyWatchlistPage untuk distyling card satu per satu
  5. Setiap card memiliki onTap() yang jika diklik maka data object Watchlist pada card tersebut dipassing ke SingleWatchlistPage untuk ditampilkan khusus pada data tersebut

Project Implementation

  1. Menambahkan ListTile() menuju MyWatchlistPage di dalam Drawer.dart
  2. Membuat file model mywatchlist bernama watchlist.dart yang berisi model dari Watchlist
    class Watchlist {
    Watchlist({
        required this.id,
        required this.watched,
        required this.title,
        required this.rating,
        required this.release_date,
        required this.review,
    });
    
  3. Melakukan fetch di dalam utils/fetch.dart ke alamat 'https://pbp-assignment-eugeniusms.herokuapp.com/mywatchlist/json/'
  4. Menambahkan inisiasi class sesuai dengan JSON yang akan difetch
    factory Watchlist.fromJson(Map<String, dynamic> json) => Watchlist(
        id: json["pk"],
        watched: json["fields"]["watched"],
        title: json["fields"]["title"],
        rating: json["fields"]["rating"],
        release_date: json["fields"]["release_date"],
        review: json["fields"]["review"],
    );
    
  5. Menambahkan object yang difetch ke dalam Flutter list di dalam fetch.dart
    List<Watchlist> listWatchlist = [];
    for (var d in data) {
        if (d != null) {
        listWatchlist.add(Watchlist.fromJson(d));
        }
    }
    
  6. Menyusun halaman MyWatchlistPage agar berisi daftar film sesuai isi elemen dari listWatchlist
  7. BONUS Menambahkan checkbox pada card
    Checkbox(
        value: snapshot.data![index].watched,
        onChanged: (bool? value) {
            setState(() {
            this.value =
                snapshot.data![index].watched
                    ? false
                    : true;
            });
        },
    ),
    
  8. BONUS Menambahkan colored outline border
    border: Border.all(
        color: snapshot.data![index].watched
            ? Colors.green
            : Colors.red,
        width: 5
    ),
    
  9. Menambahkan halaman detail SingleWatchlistPage dengan cara passing object Watchlist as a data ke widget SingleWatchlistPage untuk ditampilkan sesuai objectnya dengan properti-propertinya
    final Watchlist data;
    SingleWatchlistPage({required this.data});
    
  10. Melakukan styling di halaman detail

Flutter

This project is a starting point for a Flutter application.

A few resources to get you started if this is your first Flutter project:

For help getting started with Flutter development, view the online documentation, which offers tutorials, samples, guidance on mobile development, and a full API reference.

About

Platform-Based Programming (CSGE602022) - Organized by the Faculty of Computer Science Universitas Indonesia, Odd Semester 2022/2023

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published