Tuesday, April 28, 2026

PPB ETS - MyMoney Notes

Membuat Aplikasi Keuangan "MyMoney Notes" dengan Jetpack Compose & Room Database

MyMoney Notes adalah aplikasi pencatatan keuangan pribadi berbasis Android yang dirancang untuk membantu pengguna mengelola arus kas (pemasukan dan pengeluaran) secara efisien. Dengan antarmuka modern menggunakan Jetpack Compose dan penyimpanan lokal yang aman menggunakan Room Database.

Anggota Kelompok:
  • Aryaka Leorgi Epridaka - 5025231117
  • Muhammad Risyad Himawan Putra - 5025231205

Akses Project:
Source Code: https://github.com/AryakaLeorgi/MyMoneyNotes
Presentasi (PPT): https://drive.google.com/file/d/1uC5WQZkmNkFck--wN4OG81x_t9ZKMs6n/view?usp=sharing
Download APK: https://github.com/AryakaLeorgi/MyMoneyNotes/releases/download/APK/MyMoney-Notes_1.0.apk
Video presentasi: https://youtu.be/aRvOIZ2ANoc


1. Deskripsi & Fitur Utama

Aplikasi ini menganut arsitektur MVVM (Model-View-ViewModel) untuk memastikan kode terstruktur dan mudah dikelola. Fitur utama meliputi:

  • Dashboard Keuangan: Pantau total saldo, pemasukan, dan pengeluaran secara real-time.
  • Statistik Visual: Grafik batang harian dan diagram lingkaran alokasi dana per kategori.
  • Riwayat Transaksi: Pencatatan detail dengan fitur Edit dan Hapus transaksi.
  • Multi-Step Wizard: Form tambah transaksi yang intuitif untuk meminimalkan kesalahan input.
  • Penyimpanan Lokal: Data tersimpan aman di perangkat menggunakan SQLite melalui Room Database.

2. MainActivity (Entry Point)

class MainActivity : ComponentActivity() { private val viewModel: TransactionViewModel by viewModels() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enableEdgeToEdge() setContent { MyMoneyNotesTheme { MyMoneyApp(viewModel) } } } }

3. Data Model (Room Entity)

@Entity(tableName = "transactions") data class Transaction( @PrimaryKey val id: String = UUID.randomUUID().toString(), val type: TransactionType, val category: String, val amount: Double, val date: Long )

4. Penjelasan Arsitektur

  • Model (Room Entity): Digunakan untuk mendefinisikan skema tabel database. Dengan Room, kita bisa berinteraksi dengan SQLite menggunakan objek Kotlin biasa tanpa perlu menulis SQL mentah yang rumit.
  • ViewModel & StateFlow: Otak dari aplikasi. ViewModel mengelola state UI secara reaktif menggunakan StateFlow. Ketika data di database berubah, UI akan otomatis memperbarui tampilannya tanpa perlu refresh manual.
  • Repository Pattern: Bertindak sebagai jembatan antara Database (DAO) dan ViewModel. Ini memastikan logika pengambilan data terpusat dan rapi.
  • Jetpack Compose UI: Seluruh tampilan dibangun secara deklaratif. Komponen seperti DailyBarChart dan TransactionRow dibuat secara modular sehingga kode sangat mudah dibaca dan dikembangkan.

5. Cara Instalasi

  1. Download file APK melalui link yang disediakan di atas.
  2. Izinkan instalasi dari sumber tidak dikenal pada pengaturan Android Anda.
  3. Buka aplikasi dan mulai catat keuangan Anda!

Tampilan Aplikasi

 

Tuesday, April 14, 2026

PPB Pertemuan 7 - Membuat Halaman Simple Login

Membuat Aplikasi Android "Login Screen" dengan Jetpack Compose

Blog ini menjelaskan cara membuat aplikasi sederhana berupa Login Screen menggunakan Jetpack Compose. Aplikasi ini memiliki fitur input email, password, tombol login, serta opsi login sosial media.

Source code lengkap dapat diakses di:
https://github.com/MRHP1/Mobile-Programming/tree/main/MyLogin


1. Struktur Program

  • MainActivity.kt
  • LoginScreen.kt
  • State Management
  • Reusable Component

2. MainActivity (Full Code)

package com.example.mylogin import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.ui.Modifier import com.example.mylogin.ui.theme.MyLoginTheme class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enableEdgeToEdge() setContent { MyLoginTheme { Surface( modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background ) { LoginScreen() } } } } }

3. LoginScreen (Full Code)

package com.example.mylogin import androidx.compose.foundation.Image import androidx.compose.foundation.layout.* import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material3.* import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.PasswordVisualTransformation import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.example.mylogin.ui.theme.MyLoginTheme @Composable fun LoginScreen() { var email by remember { mutableStateOf("") } var password by remember { mutableStateOf("") } Column( modifier = Modifier .fillMaxSize() .padding(24.dp), verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally ) { Image( painter = painterResource(id = R.drawable.a), contentDescription = "Login logo", modifier = Modifier.size(240.dp) ) Spacer(modifier = Modifier.height(32.dp)) Text( text = "Welcome Back", fontSize = 28.sp, fontWeight = FontWeight.Bold ) Text( text = "Login to your account", color = MaterialTheme.colorScheme.secondary ) Spacer(modifier = Modifier.height(32.dp)) OutlinedTextField( value = email, onValueChange = { email = it }, label = { Text("Email Address") }, modifier = Modifier.fillMaxWidth(), keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Email), singleLine = true ) Spacer(modifier = Modifier.height(16.dp)) OutlinedTextField( value = password, onValueChange = { password = it }, label = { Text("Password") }, modifier = Modifier.fillMaxWidth(), visualTransformation = PasswordVisualTransformation(), keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password), singleLine = true ) Spacer(modifier = Modifier.height(16.dp)) Button( onClick = { }, modifier = Modifier.fillMaxWidth() ) { Text("Login") } } }

4. Penjelasan 

  • State
        
    State digunakan untuk menyimpan nilai yang berubah selama aplikasi berjalan, seperti email dan password yang diinput user. Dalam Jetpack Compose, state dibuat menggunakan remember dan mutableStateOf. remember berfungsi agar nilai tetap tersimpan selama composable masih aktif (tidak reset setiap recomposition), sedangkan mutableStateOf memungkinkan nilai tersebut berubah. Ketika nilai state berubah, Compose akan otomatis melakukan recomposition sehingga UI langsung ikut ter-update tanpa perlu manual refresh.
  • Column
        
    Column adalah komponen layout yang digunakan untuk menyusun elemen UI secara vertikal (dari atas ke bawah). Semua komponen seperti gambar, teks, input field, dan tombol diletakkan di dalam Column agar tersusun rapi. Properti seperti verticalArrangement dan horizontalAlignment dapat digunakan untuk mengatur posisi konten (misalnya di tengah layar), sementara Modifier.padding memberikan jarak agar tampilan tidak terlalu mepet. 
  • OutlinedTextField
     
       OutlinedTextField merupakan komponen input dari Material Design yang digunakan untuk menerima input dari pengguna. Pada aplikasi ini digunakan untuk email dan password. Properti value menampung nilai input, sedangkan onValueChange akan dipanggil setiap kali user mengetik, sehingga state akan langsung diperbarui. Untuk password, biasanya ditambahkan visualTransformation agar teks disembunyikan, serta keyboardOptions untuk menyesuaikan tipe keyboard (email atau password).
  • Button
      
     Button digunakan sebagai pemicu aksi, dalam hal ini proses login. Saat tombol ditekan, kode di dalam onClick akan dijalankan, misalnya untuk mengambil nilai email dan password dari state, melakukan validasi, atau mengirim data ke server/API. Button juga bisa dikustomisasi ukurannya dengan Modifier dan biasanya dibuat full width agar lebih mudah diakses oleh pengguna. 

5. Cara Menjalankan

  1. Buka Android Studio
  2. Buat project Compose
  3. Copy code di atas
  4. Tambahkan gambar di drawable
  5. Run aplikasi

Hasil Tampilan

Friday, April 10, 2026

PPB Pertemuan 6 - Kalkulator Sederhana

Membuat Aplikasi Android "Simple Calculator" dengan Jetpack Compose

Blog ini akan menjelaskan cara membuat aplikasi sederhana berupa Calculator, yaitu aplikasi kalkulator sederhana yang memuat fitur basic seperti penjumlahan, pengurangan, perkalian, dan pembagian menggunakan input dari user.


1. Struktur Dasar Program

Program terdiri dari beberapa bagian utama:

  • MainActivity
  • Composable function
  • State
  • Logic perhitungan

2. MainActivity

Activity utama menggunakan setContent untuk menampilkan UI Compose dan memanggil fungsi CalculatorScreen.

class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { CalculatorScreen() } } }
  • setContent digunakan untuk menampilkan UI berbasis Compose
  • CalculatorScreen() adalah tampilan utama aplikasi

3. Composable CalculatorScreen

Fungsi ini adalah UI utama yang berisi input angka, operator, tombol, dan hasil perhitungan.

@Composable fun CalculatorScreen() { var num1 by remember { mutableStateOf("") } var num2 by remember { mutableStateOf("") } var operator by remember { mutableStateOf("+") } var result by remember { mutableStateOf("") } Column(modifier = Modifier.padding(16.dp)) { OutlinedTextField( value = num1, onValueChange = { num1 = it }, label = { Text("Number 1") } ) OutlinedTextField( value = operator, onValueChange = { operator = it }, label = { Text("Operator") } ) OutlinedTextField( value = num2, onValueChange = { num2 = it }, label = { Text("Number 2") } ) Button(onClick = { /* perhitungan */ }) { Text("Calculate") } Text(text = "Result: $result") } }
  • OutlinedTextField digunakan untuk input user
  • Button untuk menjalankan perhitungan
  • Text menampilkan hasil

4. State Management

State digunakan untuk menyimpan nilai input dan hasil perhitungan menggunakan remember.

var num1 by remember { mutableStateOf("") } var num2 by remember { mutableStateOf("") } var operator by remember { mutableStateOf("+") } var result by remember { mutableStateOf("") }
  • remember menyimpan state selama composable aktif
  • mutableStateOf membuat state dapat berubah

5. Logic Perhitungan

Perhitungan dilakukan saat tombol ditekan dengan validasi input dan operator.

val n1 = num1.toDoubleOrNull() val n2 = num2.toDoubleOrNull() result = if (n1 == null || n2 == null) { "Invalid input" } else { when (operator) { "+" -> (n1 + n2).toString() "-" -> (n1 - n2).toString() "*" -> (n1 * n2).toString() "/" -> if (n2 != 0.0) (n1 / n2).toString() else "Cannot divide by zero" else -> "Invalid operator" } }
  • toDoubleOrNull() untuk validasi input angka
  • when untuk menentukan operasi matematika
  • Penanganan error seperti input tidak valid dan pembagian nol

6. Cara Menjalankan Aplikasi

  1. Buka Android Studio
  2. Buat project baru dengan template Empty Activity (Compose)
  3. Masukkan kode ke file MainActivity.kt
  4. Jalankan emulator atau device
  5. Klik tombol Run
  6. Masukkan angka dan operator, lalu tekan Calculate

Hasil Tampilan Aplikasi

Aplikasi akan menampilkan dua input angka, satu input operator, tombol calculate, dan hasil perhitungan di bagian bawah. 

 

 

PPB EAS - Aplikasi Member Timezone

Manajemen Keanggotaan & Loyalty Program Timezone dengan Room Database dan Jetpack Compose Aryaka Leorgi Epridaka - 5025231117 Muhammad ...