Skip to main content

Simple Calculator With ViewModel and LIveData



This is a simple calculator with basic mathematical operations.
You can download full source code of this project from Github
https://github.com/arunkfedex/SimpleCalculator 
We are using ViewModel and LiveData so we need to add those dependencies in build.gradle file.

build.gradle
plugins {
    id 'com.android.application'
    id 'kotlin-android'
}
android {
    compileSdk 30
    defaultConfig {
        applicationId "com.arun.androidtutsforu.simplecalculator"
        minSdk 21
        targetSdk 30
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = '1.8'
    }
    buildFeatures{
        dataBinding true
    }
}
dependencies {
    def lifecycle_version = "2.4.0-alpha03"
    implementation 'androidx.core:core-ktx:1.6.0'
    implementation 'androidx.appcompat:appcompat:1.3.1'
    implementation 'com.google.android.material:material:1.4.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.0'
    implementation 'androidx.legacy:legacy-support-v4:1.0.0'
    implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"
    implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version"
    implementation "androidx.fragment:fragment-ktx:1.3.6"
    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'

}
Next is our layout file activity_main.xml 
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
    tools:context=".MainActivity">
<fragment
    android:id="@+id/simpleCalcFragment"
    android:name="com.arun.androidtutsforu.simplecalculator.calculator.SimpleCalcFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

</androidx.constraintlayout.widget.ConstraintLayout>                 
                         
our activity_main.xml file is just holding our fragment , which contains all the ui elements 
fragment_simple_calc.xml
                         
 <?xml version="1.0" encoding="utf-8"?>
<layout 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">

    <data>
     <variable
         name="simpleCalcViewModel"
         type="com.arun.androidtutsforu.simplecalculator.calculator.SimpleCalcViewModel" />
    </data>
    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".calculator.SimpleCalcFragment">
        <TextView
            android:id="@+id/number"
            android:layout_width="0dp"
            android:layout_height="100dp"
            android:layout_marginStart="8dp"
            android:layout_marginTop="8dp"
            android:layout_marginEnd="8dp"
            android:text="@{simpleCalcViewModel.number}"
            android:textAlignment="viewEnd"
            android:textColor="@color/black"
            android:textSize="35sp"
            android:textStyle="bold"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
        <TextView
            android:id="@+id/result"
            android:layout_width="0dp"
            android:layout_height="100dp"
            android:layout_marginStart="8dp"
            android:layout_marginEnd="8dp"
            android:text="@{simpleCalcViewModel.result}"
            android:textAlignment="viewEnd"
            android:textColor="@color/black"
            android:textSize="45sp"
            android:textStyle="bold"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/number" />

        <Button
            android:id="@+id/zero"
            style="@style/Calcbutton"
            android:onClick="@{()->simpleCalcViewModel.numberClicked(`0`)}"
            android:text="0"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toStartOf="@+id/dot"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toStartOf="parent" />
        <Button
            android:id="@+id/dot"
            style="@style/Calcbutton"
            android:onClick="@{()->simpleCalcViewModel.numberClicked(`.`)}"
            android:text="."
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toStartOf="@+id/equal"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toEndOf="@+id/zero" />
        <Button
            android:id="@+id/equal"
            style="@style/Calcbutton"
            android:onClick="@{()->simpleCalcViewModel.equalToClicked()}"
            android:text="="
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toStartOf="@+id/plus"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toEndOf="@+id/dot" />
        <Button
            android:id="@+id/plus"
            style="@style/Calcbutton"
            android:onClick="@{()->simpleCalcViewModel.operatorClicked(`+`)}"
            android:text="+"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toEndOf="@+id/equal" />
        <Button
            android:id="@+id/one"
            style="@style/Calcbutton"
            android:onClick="@{()->simpleCalcViewModel.numberClicked(`1`)}"
            android:text="1"
            app:layout_constraintBottom_toTopOf="@+id/zero"
            app:layout_constraintEnd_toStartOf="@+id/two"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toStartOf="parent" />
        <Button
            android:id="@+id/two"
            style="@style/Calcbutton"
            android:onClick="@{()->simpleCalcViewModel.numberClicked(`2`)}"
            android:text="2"
            app:layout_constraintBottom_toTopOf="@+id/dot"
            app:layout_constraintEnd_toStartOf="@+id/three"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toEndOf="@+id/one" />
        <Button
            android:id="@+id/three"
            style="@style/Calcbutton"
            android:onClick="@{()->simpleCalcViewModel.numberClicked(`3`)}"
            android:text="3"
            app:layout_constraintBottom_toTopOf="@+id/equal"
            app:layout_constraintEnd_toStartOf="@+id/minus"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toEndOf="@+id/two" />
        <Button
            android:id="@+id/minus"
            style="@style/Calcbutton"
            android:onClick="@{()->simpleCalcViewModel.operatorClicked(`-`)}"
            android:text="-"
            app:layout_constraintBottom_toTopOf="@+id/plus"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toEndOf="@+id/three" />
        <Button
            android:id="@+id/four"
            style="@style/Calcbutton"
            android:onClick="@{()->simpleCalcViewModel.numberClicked(`4`)}"
            android:text="4"
            app:layout_constraintBottom_toTopOf="@+id/one"
            app:layout_constraintEnd_toStartOf="@+id/five"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toStartOf="parent" />
        <Button
            android:id="@+id/five"
            style="@style/Calcbutton"
            android:onClick="@{()->simpleCalcViewModel.numberClicked(`5`)}"
            android:text="5"
            app:layout_constraintBottom_toTopOf="@+id/two"
            app:layout_constraintEnd_toStartOf="@+id/six"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toEndOf="@+id/four" />
        <Button
            android:id="@+id/six"
            style="@style/Calcbutton"
            android:onClick="@{()->simpleCalcViewModel.numberClicked(`6`)}"
            android:text="6"
            app:layout_constraintBottom_toTopOf="@+id/three"
            app:layout_constraintEnd_toStartOf="@+id/multiply"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toEndOf="@+id/five" />
        <Button
            android:id="@+id/multiply"
            style="@style/Calcbutton"
            android:onClick="@{()->simpleCalcViewModel.operatorClicked(`*`)}"
            android:text="*"
            app:layout_constraintBottom_toTopOf="@+id/minus"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toEndOf="@+id/six" />
        <Button
            android:id="@+id/seven"
            style="@style/Calcbutton"
            android:onClick="@{()->simpleCalcViewModel.numberClicked(`7`)}"
            android:text="7"
            app:layout_constraintBottom_toTopOf="@+id/four"
            app:layout_constraintEnd_toStartOf="@+id/eight"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toStartOf="parent" />
        <Button
            android:id="@+id/eight"
            style="@style/Calcbutton"
            android:onClick="@{()->simpleCalcViewModel.numberClicked(`8`)}"
            android:text="8"
            app:layout_constraintBottom_toTopOf="@+id/five"
            app:layout_constraintEnd_toStartOf="@+id/nine"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toEndOf="@+id/seven" />
        <Button
            android:id="@+id/nine"
            style="@style/Calcbutton"
            android:onClick="@{()->simpleCalcViewModel.numberClicked(`9`)}"
            android:text="9"
            app:layout_constraintBottom_toTopOf="@+id/six"
            app:layout_constraintEnd_toStartOf="@+id/divide"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toEndOf="@+id/eight" />
        <Button
            android:id="@+id/divide"
            style="@style/Calcbutton"
            android:onClick="@{()->simpleCalcViewModel.operatorClicked(`/`)}"
            android:text="/"
            app:layout_constraintBottom_toTopOf="@+id/multiply"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toEndOf="@+id/nine" />
        <Button
            android:id="@+id/clear_all"
            style="@style/Calcbutton"
            android:layout_marginTop="8dp"
            android:onClick="@{()->simpleCalcViewModel.clearAllclicked()}"
            android:text="Clear"
            app:layout_constraintBottom_toTopOf="@+id/nine"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/result" />
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>               
Next is our MainActivity.kt

package com.arun.androidtutsforu.simplecalculator
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
}
All our ui elements are managed by our fragment 
SimpleCalcFragment.kt

package com.arun.androidtutsforu.simplecalculator.calculator

import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels
import com.arun.androidtutsforu.simplecalculator.R
import com.arun.androidtutsforu.simplecalculator.databinding.FragmentSimpleCalcBinding
class SimpleCalcFragment : Fragment() {
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val binding = FragmentSimpleCalcBinding.inflate(inflater,container,false)
        val viewModel :SimpleCalcViewModel by activityViewModels()
        binding.simpleCalcViewModel =viewModel
        binding.setLifecycleOwner(this)
        return binding.root
    }
}
In new android architecture fragments should only display data. All the data calculation and decision making should be done in ViewModel
our SimpleCalcViewModel.kt
package com.arun.androidtutsforu.simplecalculator.calculator
import android.widget.Toast
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import java.math.BigDecimal
import java.math.RoundingMode
import kotlin.math.floor
class SimpleCalcViewModel : ViewModel() {
    var secondNum  = 0.0
    var opcode :String =""
    var firstNumStr =""
    var secondNumStr =""
    var firstNum =0.0
    var isFirst:Boolean = true
    private var _number = MutableLiveData<String>()
    val number:LiveData<String>
     get() = _number
    private var _result = MutableLiveData<String>()
    val result:LiveData<String>
      get() = _result

    init{
      _number.value=""
      _result.value=""
    }
    fun numberClicked(num:String){
         _number.value = _number.value+num
        if(isFirst) {
            firstNumStr = firstNumStr + num
            firstNum =firstNumStr.toDouble()
        }else{
            secondNumStr = secondNumStr + num
            secondNum = secondNumStr.toDouble()
        }
    }
    fun operatorClicked(operator :String){

          _number.value=_number.value+operator
          opcode=operator
          isFirst=false

    }
    fun equalToClicked(){
        when(opcode){
            "+"->_result.value=(firstNum+secondNum).toString()
            "-"->_result.value=(firstNum-secondNum).toString()
            "*"->_result.value=(firstNum*secondNum).toString()
            "/"->_result.value=(firstNum/secondNum).toString()
            else->0
        }
        clear()
    }
    fun clearAllclicked(){
        clear()
        _number.value=""
        _result.value=""
    }
    fun clear(){
        isFirst=true
        firstNumStr=""
        secondNumStr=""
        firstNum=0.0
        secondNum=0.0
    }

}
You  can download full source code of this project from github 

Comments

Popular posts

Simple Calculator in Android

You can view new updated simple calculator with ViemModel and LiveData in my new blog    https://androidtuts4u.blogspot.com/2021/10/simple-calculator-with-viewmodel-and.html To create a calculator first  we need to create the layout of the calculator. Layout  is created  using XML file given below <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"     xmlns:tools="http://schemas.android.com/tools"     android:layout_width="match_parent"     android:layout_height="match_parent" >  <EditText     android:id="@+id/result_id"       android:layout_width="fill_parent"     android:layout_height="120dp"   />  <Button    android:id="@+id/Btn7_id"      android:layout_width="70dp"    android:layout_height="60dp"    android:layout_below="@id/result_id"   ...

Android External database : Using database in "assets" folder

The best way to create a database application in android is , using an exteranal database . ie, we can create database  using tools like N avicat  , SQLite Browser  and copy this database into our application .This  method is more flexible and easy than creating a database in our application . This is a simple application using external database file.Application will insert data into database and show data from the database in a customized list view.  Screenshots of this application are MainActivity This is the first activity of this application . When  Register Here button is pressed it will start Registration Activity Editing of the entries can be done with a Long Click on the listView items. you can download the source code of this project from  google drive  https://drive.google.com/folderview?id=0BySLpWhqmbbdY3JHMkZRZFN0bEE&usp=sharing click on the above link ->sign into  your  google account ->a...

Android CardView And SQLite example

SQLite Database Android provides several options to save persistent application data. SQlite database is ideal for saving repeating and structured data . Using Sqlite we can save structured data in a private database.  This is a simple application showing use of Sqlite database in android . This example shows how to perform Insert , select , update and delete operation in  SQlite database Screenshots of our sample application                                                                                                                      This is a Registration app. New user can register by clicking registration button . Registered  users are shown in car...