Tugas 5 PPB A 2025 - Aplikasi Kalkulator

 Nama     : Rayhan Arvianta Bayuputra

NRP        : 5025211217

Kelas      : PPB A

TA            : 2024 (Genap)


Aplikasi Kalkulator

Pada pertemuan kali ini, kami membuat sebuah aplikasi kalkulator sederhana. Berikut cuplikannya:


Berikut cuplikan kode dari aplikasi tersebut

package com.example.mycalculator

import android.os.Bundle
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.example.mycalculator.ui.theme.MyCalculatorTheme

class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
MyCalculatorTheme {
CalculatorApp()
}
}
}
}

@Composable
fun CalculatorApp() {
var num1 by remember { mutableStateOf("") }
var num2 by remember { mutableStateOf("") }
var res by remember { mutableStateOf("") }

val context = LocalContext.current
val focusManager = LocalFocusManager.current

Column(
modifier = Modifier
.fillMaxSize()
.padding(24.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Text(
text = "Calculator App",
fontSize = 24.sp,
color = Color.DarkGray,
fontWeight = FontWeight.Bold
)
Spacer(modifier = Modifier.height(16.dp))

TextField(
value = num1,
onValueChange = { num1 = it },
singleLine = true,
label = { Text("First number") },
modifier = Modifier.fillMaxWidth()
)

Spacer(modifier = Modifier.height(8.dp))

TextField(
value = num2,
onValueChange = { num2 = it },
singleLine = true,
label = { Text("Second number") },
modifier = Modifier.fillMaxWidth()
)

Spacer(modifier = Modifier.height(16.dp))

Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween
) {
CalculatorButton("Add") {
calculate(num1, num2, context, focusManager) { a, b -> a + b }
?.let { res = it }
}
CalculatorButton("Sub") {
calculate(num1, num2, context, focusManager) { a, b -> a - b }
?.let { res = it }
}
CalculatorButton("Mul") {
calculate(num1, num2, context, focusManager) { a, b -> a * b }
?.let { res = it }
}
CalculatorButton("Div") {
val b = num2.toIntOrNull()
if (b == 0) {
Toast.makeText(context, "Cannot divide by zero", Toast.LENGTH_SHORT).show()
focusManager.clearFocus()
} else {
calculate(num1, num2, context, focusManager) { a, b -> a / b }
?.let { res = it }
}
}
}

Card(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 16.dp),
elevation = CardDefaults.cardElevation(defaultElevation = 6.dp),
shape = RoundedCornerShape(12.dp),
colors = CardDefaults.cardColors(
containerColor = MaterialTheme.colorScheme.primaryContainer
)
) {
if (res.isNotEmpty()) {
Text(
text = res,
fontSize = 30.sp,
color = MaterialTheme.colorScheme.onPrimaryContainer.copy(alpha = 0.7f),
modifier = Modifier.fillMaxWidth().padding(12.dp),
textAlign = TextAlign.Center
)
}
}
}
}

@Composable
fun CalculatorButton(label: String, onClick: () -> Unit) {
Button(onClick = onClick) {
Text(text = label)
}
}

fun calculate(
num1: String,
num2: String,
context: android.content.Context,
focusManager: androidx.compose.ui.focus.FocusManager,
operation: (Int, Int) -> Int
): String? {
val a = num1.toIntOrNull()
val b = num2.toIntOrNull()

return if (a != null && b != null) {
val result = operation(a, b)
Toast.makeText(context, "Result: $result", Toast.LENGTH_SHORT).show()
focusManager.clearFocus()
result.toString()
} else {
Toast.makeText(context, "Please input a valid number", Toast.LENGTH_SHORT).show()
focusManager.clearFocus()
null
}
}

@Preview(showBackground = true)
@Composable
fun CalculatorPreview() {
MyCalculatorTheme {
CalculatorApp()
}
}

MainActivity Class

Kelas MainActivity merupakan titik masuk utama aplikasi, yang merupakan turunan dari ComponentActivity. Di dalam metode onCreate(), fungsi setContent {} digunakan untuk menginisialisasi tampilan antarmuka pengguna menggunakan Jetpack Compose.

Tema aplikasi MyCalculatorTheme diterapkan sebagai wrapper utama untuk seluruh UI. Fungsi CalculatorApp() kemudian dipanggil untuk membangun dan menampilkan tampilan utama aplikasi kalkulator.

CalculatorApp Function

Fungsi CalculatorApp() bertanggung jawab untuk menyusun dan menampilkan seluruh komponen antarmuka pengguna aplikasi kalkulator.

Beberapa elemen utama yang ditampilkan dalam fungsi ini meliputi:

  • TextField (First number dan Second number): Digunakan untuk menginput dua nilai numerik yang akan dikalkulasi. Properti singleLine = true digunakan agar input tetap satu baris dan tidak menerima karakter newline dari tombol Enter.
  • Row berisi Button (Add, Sub, Mul, Div): Masing-masing tombol ini akan menjalankan fungsi perhitungan sesuai dengan operasi yang dipilih (penjumlahan, pengurangan, perkalian, dan pembagian). Hasilnya akan disimpan ke dalam state res dan juga ditampilkan melalui Toast.
  • Card (Hasil Kalkulasi): Hasil kalkulasi akan ditampilkan secara visual dalam bentuk teks besar di dalam sebuah Card. Teks ini hanya akan muncul jika nilai res tidak kosong.
  • Fokus dan Validasi Input: Aplikasi menggunakan LocalFocusManager untuk menghilangkan fokus dari TextField dan menyembunyikan keyboard saat tombol ditekan. Input divalidasi menggunakan toIntOrNull() untuk memastikan hanya angka valid yang dapat dikalkulasikan, serta menangani kondisi khusus seperti pembagian dengan nol.

CalculatorButton Function

Fungsi CalculatorButton() merupakan komponen reusable yang menerima teks label dan aksi onClick. Fungsi ini menyederhanakan pembuatan tombol kalkulasi, dan digunakan oleh keempat tombol operasi dasar (Add, Sub, Mul, dan Div).

calculate Function

Fungsi calculate() adalah inti dari logika kalkulasi. Fungsi ini menerima dua string input (num1 dan num2), lalu mencoba mengonversinya menjadi Int menggunakan toIntOrNull(). Jika kedua input valid, maka hasil dari operasi (yang didefinisikan melalui lambda operation) akan dihitung dan ditampilkan melalui Toast serta dikembalikan sebagai string. Jika input tidak valid, maka pesan peringatan akan ditampilkan dan fungsi mengembalikan null.


Demo Aplikasi

Github Repository: https://github.com/arvianta/PPB_Week5_SimpleCalculator

Comments