Calculator App - Android Studio - Kotlin
How to develop a complete Calculator App using Android Studio and Kotlin
I’ve created a modern calculator app using Android Studio (Java) with a clean and colorful interface. It supports all standard arithmetic operations, including addition, subtraction, multiplication, division, brackets, and percentages (%).
The app accurately handles expressions like:
25+(10/2)-5*(5%*2)+20+50% = 74.25
Designed with a responsive layout, bright orange and blue buttons, and smooth calculation handling — it’s perfect for anyone learning Android development or wanting to build a fully functional calculator UI from scratch.
Code
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity"> <TextView android:id="@+id/solution_tv" android:layout_width="match_parent" android:layout_height="0dp" android:layout_marginStart="16dp" android:layout_marginTop="16dp" android:layout_marginEnd="16dp" android:layout_marginBottom="16dp" android:layout_weight="1" android:textAlignment="textEnd" android:textColor="@color/black" android:textSize="18sp" tools:text="25+(10/2)-5*(5%*2)+20+50%" /> <TextView android:id="@+id/result_tv" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="16dp" android:text="0" android:textAlignment="textEnd" android:textColor="@color/black" android:textSize="24sp" tools:text="=74.25" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#F1F1F1" android:orientation="vertical" android:paddingHorizontal="4dp" android:paddingVertical="8dp"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="end" android:orientation="horizontal"> <Space android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="4dp" android:layout_weight="0.67" /> <com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton android:id="@+id/button_ac" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="4dp" android:layout_weight="1" android:backgroundTint="#FFC107" android:minHeight="60dp" android:text="AC" android:textColor="#F44336" android:textSize="22sp" android:textStyle="bold" app:cornerRadius="16dp" /> <com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton android:id="@+id/button_c" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="4dp" android:layout_weight="1" android:backgroundTint="#FFC107" android:minHeight="60dp" android:text="C" android:textColor="#F44336" android:textSize="22sp" android:textStyle="bold" app:cornerRadius="16dp" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:orientation="horizontal"> <com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton android:id="@+id/button_open_bracket" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="4dp" android:layout_weight="1" android:backgroundTint="#FF9800" android:minHeight="60dp" android:text="(" android:textColor="@color/white" android:textSize="22sp" android:textStyle="bold" app:cornerRadius="16dp" /> <com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton android:id="@+id/button_close_bracket" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="4dp" android:layout_weight="1" android:backgroundTint="#FF9800" android:minHeight="60dp" android:text=")" android:textColor="@color/white" android:textSize="22sp" android:textStyle="bold" app:cornerRadius="16dp" /> <com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton android:id="@+id/button_modular" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="4dp" android:layout_weight="1" android:backgroundTint="#FF9800" android:minHeight="60dp" android:text="%" android:textColor="@color/white" android:textSize="22sp" android:textStyle="bold" app:cornerRadius="16dp" /> <com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton android:id="@+id/button_divide" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="4dp" android:layout_weight="1" android:backgroundTint="#FF9800" android:minHeight="60dp" android:text="/" android:textColor="@color/white" android:textSize="22sp" android:textStyle="bold" app:cornerRadius="16dp" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:orientation="horizontal"> <com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton android:id="@+id/button_7" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="4dp" android:layout_weight="1" android:backgroundTint="#2196F3" android:minHeight="60dp" android:text="7" android:textColor="@color/white" android:textSize="22sp" android:textStyle="bold" app:cornerRadius="16dp" /> <com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton android:id="@+id/button_8" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="4dp" android:layout_weight="1" android:backgroundTint="#2196F3" android:minHeight="60dp" android:text="8" android:textColor="@color/white" android:textSize="22sp" android:textStyle="bold" app:cornerRadius="16dp" /> <com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton android:id="@+id/button_9" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="4dp" android:layout_weight="1" android:backgroundTint="#2196F3" android:minHeight="60dp" android:text="9" android:textColor="@color/white" android:textSize="22sp" android:textStyle="bold" app:cornerRadius="16dp" /> <com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton android:id="@+id/button_multiply" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="4dp" android:layout_weight="1" android:backgroundTint="#FF9800" android:minHeight="60dp" android:text="*" android:textColor="@color/white" android:textSize="22sp" android:textStyle="bold" app:cornerRadius="16dp" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:orientation="horizontal"> <com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton android:id="@+id/button_4" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="4dp" android:layout_weight="1" android:backgroundTint="#2196F3" android:minHeight="60dp" android:text="4" android:textColor="@color/white" android:textSize="22sp" android:textStyle="bold" app:cornerRadius="16dp" /> <com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton android:id="@+id/button_5" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="4dp" android:layout_weight="1" android:backgroundTint="#2196F3" android:minHeight="60dp" android:text="5" android:textColor="@color/white" android:textSize="22sp" android:textStyle="bold" app:cornerRadius="16dp" /> <com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton android:id="@+id/button_6" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="4dp" android:layout_weight="1" android:backgroundTint="#2196F3" android:minHeight="60dp" android:text="6" android:textColor="@color/white" android:textSize="22sp" android:textStyle="bold" app:cornerRadius="16dp" /> <com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton android:id="@+id/button_plus" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="4dp" android:layout_weight="1" android:backgroundTint="#FF9800" android:minHeight="60dp" android:text="+" android:textColor="@color/white" android:textSize="22sp" android:textStyle="bold" app:cornerRadius="16dp" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:orientation="horizontal"> <com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton android:id="@+id/button_1" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="4dp" android:layout_weight="1" android:backgroundTint="#2196F3" android:minHeight="60dp" android:text="1" android:textColor="@color/white" android:textSize="22sp" android:textStyle="bold" app:cornerRadius="16dp" /> <com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton android:id="@+id/button_2" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="4dp" android:layout_weight="1" android:backgroundTint="#2196F3" android:minHeight="60dp" android:text="2" android:textColor="@color/white" android:textSize="22sp" android:textStyle="bold" app:cornerRadius="16dp" /> <com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton android:id="@+id/button_3" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="4dp" android:layout_weight="1" android:backgroundTint="#2196F3" android:minHeight="60dp" android:text="3" android:textColor="@color/white" android:textSize="22sp" android:textStyle="bold" app:cornerRadius="16dp" /> <com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton android:id="@+id/button_minus" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="4dp" android:layout_weight="1" android:backgroundTint="#FF9800" android:minHeight="60dp" android:text="-" android:textColor="@color/white" android:textSize="22sp" android:textStyle="bold" app:cornerRadius="16dp" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:orientation="horizontal"> <com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton android:id="@+id/button_0" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="4dp" android:layout_weight=".67" android:backgroundTint="#2196F3" android:minHeight="60dp" android:text="0" android:textColor="@color/white" android:textSize="22sp" android:textStyle="bold" app:cornerRadius="16dp" /> <com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton android:id="@+id/button_dot" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="4dp" android:layout_weight="1" android:backgroundTint="#2196F3" android:minHeight="60dp" android:text="." android:textColor="@color/white" android:textSize="22sp" android:textStyle="bold" app:cornerRadius="16dp" /> <com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton android:id="@+id/button_equals" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="4dp" android:layout_weight="1" android:backgroundTint="#FF9800" android:minHeight="60dp" android:text="=" android:textColor="@color/white" android:textSize="22sp" android:textStyle="bold" app:cornerRadius="16dp" /> </LinearLayout> </LinearLayout> </LinearLayout>
MainActivity.kt
package com.technifysoft.myapplication import android.os.Bundle import android.view.View import android.widget.Button import androidx.activity.enableEdgeToEdge import androidx.appcompat.app.AppCompatActivity import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat import com.technifysoft.myapplication.databinding.ActivityMainBinding class MainActivityy : AppCompatActivity(), View.OnClickListener { private lateinit var binding: ActivityMainBinding private var currentExpression = "" override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enableEdgeToEdge() binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) ViewCompat.setOnApplyWindowInsetsListener(binding.root) { v, insets -> val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()) v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom) insets } val buttons = listOf( binding.button0, binding.button1, binding.button2, binding.button3, binding.button4, binding.button5, binding.button6, binding.button7, binding.button8, binding.button9, binding.buttonPlus, binding.buttonMinus, binding.buttonMultiply, binding.buttonDivide, binding.buttonDot, binding.buttonOpenBracket, binding.buttonCloseBracket, binding.buttonC, binding.buttonAc, binding.buttonEquals, binding.buttonModular ) buttons.forEach { it.setOnClickListener(this) } } override fun onClick(v: View) { val button = v as Button val buttonText = button.text.toString() val viewId = v.id when (viewId) { binding.buttonEquals.id -> { val result = binding.resultTv.text.toString() if (result != "Err") { currentExpression = result binding.solutionTv.text = currentExpression } return } binding.buttonAc.id -> { currentExpression = "" binding.solutionTv.text = "" binding.resultTv.text = "0" return } binding.buttonC.id -> { if (currentExpression.isNotEmpty()) { currentExpression = currentExpression.dropLast(1) } } else -> { currentExpression += buttonText } } val displayExpression = formatExpressionForDisplay(currentExpression) binding.solutionTv.text = displayExpression val finalResult = getResult(currentExpression) if (finalResult != "Err") { binding.resultTv.text = finalResult } } private fun formatExpressionForDisplay(expression: String): String { var formatted = expression formatted = formatted.replace(Regex("(?<=\\d)(?=\\()"), "*") // 5( -> 5*( formatted = formatted.replace(Regex("(?<=\\))(?=\\d)"), "*") // )5 -> )*5 formatted = formatted.replace(Regex("(?<=\\))(?=\\()"), "*") // )( -> )*( formatted = formatted.replace(Regex("(?<=%)(?=\\d|\\()"), "*") // 5%2 -> 5%*2 or 5%( -> 5%*( return formatted } private fun getResult(data: String): String { try { // Handle "100+10%" or "200-15%" val percentPattern = Regex("(.+)([+-])(\\d*\\.?\\d+)%") val match = percentPattern.matchEntire(data) if (match != null) { val (baseExpr, operator, percentValueStr) = match.destructured val baseResultStr = getResult(baseExpr) val baseValue = baseResultStr.toDouble() val percentValue = percentValueStr.toDouble() val percentOfBase = baseValue * (percentValue / 100.0) val finalResult = if (operator == "+") baseValue + percentOfBase else baseValue - percentOfBase return finalResult.toString() } // Inline percentages (5% → 0.05) var parsedData = data.replace(Regex("(\\d*\\.?\\d+)%")) { val value = it.groupValues[1].toDouble() "(${value / 100.0})" } // Implicit multiplication parsedData = parsedData .replace(Regex("(?<=\\d)(?=\\()"), "*") .replace(Regex("(?<=\\))(?=\\d)"), "*") .replace(Regex("(?<=\\))(?=\\()"), "*") return eval(parsedData).toString() } catch (e: Exception) { return "Err" } } private fun eval(str: String): Double { return object { var pos = -1 var ch = 0 fun nextChar() { ch = if (++pos < str.length) str[pos].code else -1 } fun eat(charToEat: Int): Boolean { while (ch == ' '.code) nextChar() return if (ch == charToEat) { nextChar() true } else false } fun parse(): Double { nextChar() val x = parseExpression() if (pos < str.length) throw RuntimeException("Unexpected: ${str[pos]}") return x } fun parseExpression(): Double { var x = parseTerm() while (true) { x = when { eat('+'.code) -> x + parseTerm() eat('-'.code) -> x - parseTerm() else -> return x } } } fun parseTerm(): Double { var x = parseFactor() while (true) { x = when { eat('*'.code) -> x * parseFactor() eat('/'.code) -> x / parseFactor() else -> return x } } } fun parseFactor(): Double { if (eat('+'.code)) return parseFactor() if (eat('-'.code)) return -parseFactor() val startPos = pos val x: Double = when { eat('('.code) -> { val result = parseExpression() eat(')'.code) result } (ch in '0'.code..'9'.code) || ch == '.'.code -> { while ((ch in '0'.code..'9'.code) || ch == '.'.code) nextChar() str.substring(startPos, pos).toDouble() } else -> throw RuntimeException("Unexpected: ${ch.toChar()}") } return x } }.parse() } }
🔍 Related Searches
- Calculator app android studio source code
- Simple calculator app android studio java
- Calculator app using java in android studio
- Android calculator project with source code
- How to make a calculator app in android studio
- Calculator app UI design android studio
- Android calculator tutorial for beginners
- Percentage calculator android app
- Calculator app using kotlin or java
- Beautiful calculator UI android studio
- Step by step calculator app android studio
- Android studio calculator XML layout
- Custom calculator buttons in android studio
- Arithmetic expression evaluator android java


Comments
Post a Comment