Membuat Aplikasi Kalkulator dengan menggunakan Kotlin


Burhanudin Rifa - 5025201191

PPB - D

Github: Link

Youtube: Link


1. MainActivity

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

  • ComponentActivity: Activity dasar yang mendukung Compose.
  • setContent { … }: Menetapkan konten Compose.
  • CalculatorTheme { … }: Menerapkan tema kustom (dibahas di bagian 6).
  • CalculatorApp(applicationContext): Memanggil composable utama, meneruskan Context untuk menampilkan Toast.

2. Composable Utama: CalculatorApp

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun CalculatorApp(applicationContext: android.content.Context) {
var num1 by remember { mutableStateOf("0") }
var num2 by remember { mutableStateOf("0") }
var resultText by remember { mutableStateOf("") }

Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
Column(
modifier = Modifier
.fillMaxSize()
.padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally
)

State


  • num1, num2 (tipe String): Menyimpan input angka.

  • resultText (tipe String): Menyimpan teks hasil operasi.

  • Semua di-wrap dengan remember { mutableStateOf(...) } agar Compose me-recompose UI saat nilainya berubah.


Surface


  • Wadah dasar, mengisi seluruh layar (fillMaxSize()) dengan warna latar dari tema.


Column


  • Menyusun elemen UI secara vertikal, dengan padding dan alignment center horizontal.

3. Judul Aplikasi

Text(
text = "Calculator",
style = MaterialTheme.typography.headlineMedium,
color = MaterialTheme.colorScheme.primary,
fontWeight = FontWeight.Bold,
modifier = Modifier.padding(bottom = 24.dp)
)

4.Tampilan Hasil

if (resultText.isNotEmpty()) {
Card(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 8.dp),
colors = CardDefaults.cardColors(
containerColor = MaterialTheme.colorScheme.primaryContainer
),
shape = RoundedCornerShape(8.dp)
) {
Text(
text = resultText,
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
textAlign = TextAlign.End,
fontSize = 24.sp,
color = MaterialTheme.colorScheme.onPrimaryContainer
)
}
}

  • if: Hanya muncul jika resultText tidak kosong.
  • Card: Wadah dengan sudut membulat dan warna container tema.
  • Text: Menampilkan hasil, rata-kanan, font size 24sp.


5. Input Angka

OutlinedTextField(
value = num1,
onValueChange = { num1 = it },
label = { Text("First Number") },
modifier = Modifier.fillMaxWidth(),
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
colors = TextFieldDefaults.outlinedTextFieldColors(
focusedBorderColor = MaterialTheme.colorScheme.primary,
unfocusedBorderColor = MaterialTheme.colorScheme.outline
)
)

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

OutlinedTextField(
value = num2,
onValueChange = { num2 = it },
label = { Text("Second Number") },
modifier = Modifier.fillMaxWidth(),
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
colors = TextFieldDefaults.outlinedTextFieldColors(
focusedBorderColor = MaterialTheme.colorScheme.primary,
unfocusedBorderColor = MaterialTheme.colorScheme.outline
)
)
  • Dua OutlinedTextField: untuk num1 dan num2. keyboardType = Number memunculkan keyboard angka. Border berwarna tema saat fokus/tidak fokus.

6.Tombol Operasi

Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceEvenly
) {
CalculatorButton(
text = "Add",
onClick = {
try {
val result = num1.toInt() + num2.toInt()
resultText = "Result: $result"
Toast.makeText(applicationContext, "Result is $result", Toast.LENGTH_SHORT).show()
} catch (e: Exception) {
Toast.makeText(applicationContext, "Invalid input", Toast.LENGTH_SHORT).show()
}
},
containerColor = MaterialTheme.colorScheme.primary
)

CalculatorButton(
text = "Sub",
onClick = {
try {
val result = num1.toInt() - num2.toInt()
resultText = "Result: $result"
Toast.makeText(applicationContext, "Result is $result", Toast.LENGTH_SHORT).show()
} catch (e: Exception) {
Toast.makeText(applicationContext, "Invalid input", Toast.LENGTH_SHORT).show()
}
},
containerColor = MaterialTheme.colorScheme.secondary
)
}

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

Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceEvenly
) {
CalculatorButton(
text = "Mul",
onClick = {
try {
val result = num1.toInt() * num2.toInt()
resultText = "Result: $result"
Toast.makeText(applicationContext, "Result is $result", Toast.LENGTH_SHORT).show()
} catch (e: Exception) {
Toast.makeText(applicationContext, "Invalid input", Toast.LENGTH_SHORT).show()
}
},
containerColor = MaterialTheme.colorScheme.tertiary
)

CalculatorButton(
text = "Div",
onClick = {
try {
if (num2.toInt() == 0) {
Toast.makeText(applicationContext, "Cannot divide by zero", Toast.LENGTH_SHORT).show()
return@CalculatorButton
}
val result = num1.toInt() / num2.toInt()
resultText = "Result: $result"
Toast.makeText(applicationContext, "Result is $result", Toast.LENGTH_SHORT).show()
} catch (e: Exception) {
Toast.makeText(applicationContext, "Invalid input", Toast.LENGTH_SHORT).show()
}
},
containerColor = MaterialTheme.colorScheme.error
)
}


  • Konversi: toInt(), ditambah, disimpan di resultText. Error handling: try/catch untuk cegah input non-angka. Toast: Menampilkan pesan hasil atau kesalahan.

7.Composable CalculatorButton
@Composable
fun CalculatorButton(
text: String,
onClick: () -> Unit,
containerColor: Color
) {
Button(
onClick = onClick,
modifier = Modifier
.width(150.dp)
.height(60.dp),
colors = ButtonDefaults.buttonColors(containerColor = containerColor),
shape = RoundedCornerShape(12.dp)
) {
Text(
text = text,
fontSize = 18.sp,
fontWeight = FontWeight.Bold
)
}
}
  • Abstraksi tombol: ukuran statis (150×60 dp), warna container dapat disesuaikan, sudut membulat.

  • Menampilkan text dengan gaya bold size 18sp.

8. Tema Kustom CalculatorTheme
@Composable
fun CalculatorTheme(content: @Composable () -> Unit) {
// Custom color scheme
val colorScheme = darkColorScheme(
primary = Color(0xFF4CAF50), // Green
onPrimary = Color.White,
primaryContainer = Color(0xFF1E3A20),
onPrimaryContainer = Color(0xFFB6F2B8),
secondary = Color(0xFF2196F3), // Blue
onSecondary = Color.White,
tertiary = Color(0xFFFF9800), // Orange
onTertiary = Color.Black,
error = Color(0xFFE91E63), // Pink
background = Color(0xFF121212), // Dark background
surface = Color(0xFF1E1E1E),
onBackground = Color.White,
onSurface = Color.White
)

MaterialTheme(
colorScheme = colorScheme,
typography = Typography(
headlineMedium = TextStyle(
fontWeight = FontWeight.Bold,
fontSize = 30.sp,
letterSpacing = 0.5.sp
),
bodyLarge = TextStyle(
fontWeight = FontWeight.Normal,
fontSize = 16.sp,
letterSpacing = 0.5.sp
)
),
content = content
)
}
  • darkColorScheme: Palet warna gelap.
  • Tipografi: Kustom untuk headlineMedium dan bodyLarge.
  • MaterialTheme membungkus seluruh UI agar menggunakan warna dan tipografi ini.




Comments

Popular posts from this blog

Aplikasi Expense Tracker - Expenz

Membuat Aplikasi Login Page Sederhana