How to create a simple Android Calculator Application

How to create a simple Android Calculator Application

In my last post I described in details How to create Android Scientific Calculator Application. I have received a lot of questions from this post and some of my readers wanted me to create a new tutorial on how to create a simple android calculator application.

You can find our new Simple Android Calculator Application that supports Android X here

We are going to use most of the methods we used with our scientific calculator application. We are going to use Button Views to represent all the button in the calculator. The display of the calculator is made up of a TextView control.

We are going to use a third party library to parse our mathematics equation and display it’s result.

For us to have a better understanding of what we are planning to achieve I have provided the interface for the simple application. Feel free to redesign your own interface if you feel you want something different or much better.

Simple Calculator

Before we start, it is important for you to understand the tools and environment I used in this application development tutorial. Feel free to use any tools you are familiar with.

Windows 7

Android Studio

Sony Xperia ZL

Min SDK 14

Target SDK 22

To create a new android application project, following the steps as stipulated below.

Go to File menu

Click on New menu

Click on Android Application

Enter Project name: AndroidSimpleCalculator

Package: com.inducesmile.androidsimplecalculator

Keep other default selections

Continue to click on next button until Finish button is active, then click on Finish Button.

If you are using Android Studio as your choice IDE, the new project will create a default

MainActivity.java file and its corresponding layout file. Open the two files because we are going to

make use of them.

Open the layout file, we are going to create our layout using Button and TextView controls. The layout code snippet is shown below.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/linearLay0"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/icons"
    android:orientation="vertical">
    <LinearLayout
        android:id="@+id/display_screen"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingBottom="8dp"
        android:paddingTop="8dp"
        android:background="@color/primary_light">
        <TextView
            android:id="@+id/display"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="right"
            android:layout_gravity="right"
            android:cursorVisible="true"
            android:textColorHint="@color/icons"
            android:paddingLeft="10dp"
            android:paddingRight="10dp"
            android:singleLine="true"
            android:text="@string/zero"
            android:textColor="@color/primary_text"
            android:textSize="60sp" />
    </LinearLayout>
    <!--first row-->
    <LinearLayout
        android:id="@+id/first_row"
        android:layout_width="match_parent"
        android:layout_weight="1"
        android:layout_marginBottom="1dp"
        android:layout_height="wrap_content">
        <Button
            android:id="@+id/ac"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:textStyle="bold"
            android:textSize="20sp"
            android:padding="8dp"
            android:layout_marginRight="1dp"
            android:textColor="@color/primary_text"
            android:background="@color/color_4"
            android:text="@string/ac" />
        <Button
            android:id="@+id/plus_minus"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:textStyle="bold"
            android:textSize="20sp"
            android:padding="8dp"
            android:layout_marginRight="1dp"
            android:textColor="@color/primary_text"
            android:background="@color/primary"
            android:text="@string/plus_minus" />
        <Button
            android:id="@+id/percent"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:textStyle="bold"
            android:textSize="20sp"
            android:padding="8dp"
            android:layout_marginRight="1dp"
            android:textColor="@color/primary_text"
            android:background="@color/primary"
            android:text="@string/percent" />
        <Button
            android:id="@+id/divide"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:textStyle="bold"
            android:textSize="20sp"
            android:padding="8dp"
            android:layout_marginRight="1dp"
            android:textColor="@color/primary_text"
            android:background="@color/primary"
            android:text="@string/divide" />
    </LinearLayout>
    <!--second row-->
    <LinearLayout
        android:id="@+id/second_row"
        android:layout_width="match_parent"
        android:layout_weight="1"
        android:layout_marginBottom="1dp"
        android:layout_height="wrap_content">
        <Button
            android:id="@+id/seven"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:textStyle="bold"
            android:textSize="20sp"
            android:textColor="@color/primary_text"
            android:padding="8dp"
            android:layout_marginRight="1dp"
            android:background="@color/primary"
            android:text="@string/seven" />
        <Button
            android:id="@+id/eight"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:textStyle="bold"
            android:textSize="20sp"
            android:padding="8dp"
            android:layout_marginRight="1dp"
            android:textColor="@color/primary_text"
            android:background="@color/primary"
            android:text="@string/eight" />
        <Button
            android:id="@+id/nine"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:textStyle="bold"
            android:textSize="20sp"
            android:padding="8dp"
            android:layout_marginRight="1dp"
            android:textColor="@color/primary_text"
            android:background="@color/primary"
            android:text="@string/nine" />
        <Button
            android:id="@+id/multiply"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:textStyle="bold"
            android:textSize="20sp"
            android:padding="8dp"
            android:layout_marginRight="1dp"
            android:textColor="@color/primary_text"
            android:background="@color/primary"
            android:text="@string/multiply" />
    </LinearLayout>
    <!--third row-->
    <LinearLayout
        android:id="@+id/third_row"
        android:layout_width="match_parent"
        android:layout_weight="1"
        android:layout_marginBottom="1dp"
        android:layout_height="wrap_content">
        <Button
            android:id="@+id/four"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:textStyle="bold"
            android:textSize="20sp"
            android:textColor="@color/primary_text"
            android:padding="8dp"
            android:layout_marginRight="1dp"
            android:background="@color/primary"
            android:text="@string/four" />
        <Button
            android:id="@+id/five"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:textStyle="bold"
            android:textSize="20sp"
            android:padding="8dp"
            android:layout_marginRight="1dp"
            android:textColor="@color/primary_text"
            android:background="@color/primary"
            android:text="@string/five" />
        <Button
            android:id="@+id/six"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:textStyle="bold"
            android:textSize="20sp"
            android:padding="8dp"
            android:layout_marginRight="1dp"
            android:textColor="@color/primary_text"
            android:background="@color/primary"
            android:text="@string/six" />
        <Button
            android:id="@+id/minus"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:textStyle="bold"
            android:textSize="20sp"
            android:padding="8dp"
            android:layout_marginRight="1dp"
            android:textColor="@color/primary_text"
            android:background="@color/primary"
            android:text="@string/minus" />
    </LinearLayout>
    <!--fourth row-->
    <LinearLayout
        android:id="@+id/four_row"
        android:layout_width="match_parent"
        android:layout_weight="1"
        android:layout_marginBottom="1dp"
        android:layout_height="wrap_content">
        <Button
            android:id="@+id/one"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:textStyle="bold"
            android:textSize="20sp"
            android:textColor="@color/primary_text"
            android:padding="8dp"
            android:layout_marginRight="1dp"
            android:background="@color/primary"
            android:text="@string/one" />
        <Button
            android:id="@+id/two"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:textStyle="bold"
            android:textSize="20sp"
            android:padding="8dp"
            android:layout_marginRight="1dp"
            android:textColor="@color/primary_text"
            android:background="@color/primary"
            android:text="@string/two" />
        <Button
            android:id="@+id/three"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:textStyle="bold"
            android:textSize="20sp"
            android:padding="8dp"
            android:layout_marginRight="1dp"
            android:textColor="@color/primary_text"
            android:background="@color/primary"
            android:text="@string/three" />
        <Button
            android:id="@+id/plus"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:textStyle="bold"
            android:textSize="20sp"
            android:padding="8dp"
            android:layout_marginRight="1dp"
            android:textColor="@color/primary_text"
            android:background="@color/primary"
            android:text="@string/plus" />
    </LinearLayout>
    <!--fifth row-->
    <LinearLayout
        android:id="@+id/five_row"
        android:layout_width="match_parent"
        android:layout_weight="1"
        android:layout_marginBottom="1dp"
        android:layout_height="wrap_content">
        <Button
            android:id="@+id/zero"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:textStyle="bold"
            android:textSize="20sp"
            android:textColor="@color/primary_text"
            android:padding="8dp"
            android:layout_marginRight="1dp"
            android:background="@color/primary"
            android:text="@string/zero" />
        <Button
            android:id="@+id/double_zero"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:textStyle="bold"
            android:textSize="20sp"
            android:padding="8dp"
            android:layout_marginRight="1dp"
            android:textColor="@color/primary_text"
            android:background="@color/primary"
            android:text="@string/double_zero" />
        <Button
            android:id="@+id/dot"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:textStyle="bold"
            android:textSize="20sp"
            android:padding="8dp"
            android:layout_marginRight="1dp"
            android:textColor="@color/primary_text"
            android:background="@color/primary"
            android:text="@string/dot" />
        <Button
            android:id="@+id/equal"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:textStyle="bold"
            android:textSize="20sp"
            android:padding="8dp"
            android:layout_marginRight="1dp"
            android:textColor="@color/primary_text"
            android:background="@color/primary"
            android:text="@string/equal" />
    </LinearLayout>
    <LinearLayout
        android:id="@+id/relativeAd"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:orientation="vertical"
        android:gravity="center">
    </LinearLayout>
</LinearLayout>

The layout code is very simple and there is nothing to explain in the code above. But if you have any question do not hesitate to contact me.

We did make use of many string values in the layout file. We have stored the string values in our project strings.xml file located in the value folder.

Open your strings.xml file and update it with the code below.

<string name="one">1</string>
<string name="two">2</string>
<string name="three">3</string>
<string name="four">4</string>
<string name="five">5</string>
<string name="six">6</string>
<string name="seven">7</string>
<string name="eight">8</string>
<string name="nine">9</string>
<string name="zero">0</string>
<string name="ac">AC</string>
<string name="plus_minus">+</string>
<string name="percent">%</string>
<string name="divide">-</string>
<string name="multiply">x</string>
<string name="minus">-</string>
<string name="plus">+</string>
<string name="double_zero">00</string>
<string name="dot">.</string>
<string name="equal">=</string>

If you are implementing a Material Design in your android application, you can copy and paste the code below for your application color. Feel free to choose colors of your choice.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="primary">#009688</color>
    <color name="primary_dark">#00796B</color>
    <color name="primary_light">#B2DFDB</color>
    <color name="accent">#CDDC39</color>
    <color name="primary_text">#212121</color>
    <color name="secondary_text">#727272</color>
    <color name="icons">#FFFFFF</color>
    <color name="divider">#B6B6B6</color>    
</resources>

Now, lets moves over to our project Activity file. In this file, we will get the handle for all of our view components. The class will implement implements View.OnClickListener and we will override the View onClick method.

In the onClick method, we will get the value of the button click and append it to the calculator display. When the equal sign of the button is clicked, we will pass the displayed equation to our parse class called Calculator. This class will evaluate the equation and display the returned result.

If the equation is not a valid equation, the evaluator will display Error message in the display screen of the calculator.

The code for the class is shown below.

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.app.AppCompatActivity;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.inducesmile.completecalculatorapp.helpers.Helper;
import com.inducesmile.completecalculatorapp.ultility.Calculator;
public class SimpleCalculatorFragment extends Fragment implements View.OnClickListener {
    private Button one, two, three, four, five, six, seven, eight, nine, zero;
    private Button plus, subtract, divide, multiply, plusMinus;
    private Button ac, percent, dot, double_zero, equal;
    private String currentDisplayedInput = "";
    private String inputToBeParsed = "";
    private TextView outputResult;
    private Calculator mCalculator;
    public SimpleCalculatorFragment() {
    }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_simple_calculator, container, false);
        ((AppCompatActivity) getActivity()).getSupportActionBar().hide();
        outputResult = (TextView)view.findViewById(R.id.display);
        outputResult.setText("");
        mCalculator = new Calculator();
        one = (Button)view.findViewById(R.id.one);
        two = (Button)view.findViewById(R.id.two);
        three = (Button)view.findViewById(R.id.three);
        four = (Button)view.findViewById(R.id.four);
        five = (Button)view.findViewById(R.id.five);
        six = (Button)view.findViewById(R.id.six);
        seven = (Button)view.findViewById(R.id.seven);
        eight = (Button)view.findViewById(R.id.eight);
        nine = (Button)view.findViewById(R.id.nine);
        zero = (Button)view.findViewById(R.id.zero);
        plus = (Button)view.findViewById(R.id.plus);
        subtract = (Button)view.findViewById(R.id.minus);
        divide = (Button)view.findViewById(R.id.divide);
        multiply = (Button)view.findViewById(R.id.multiply);
        plusMinus = (Button)view.findViewById(R.id.plus_minus);
        ac = (Button)view.findViewById(R.id.ac);
        percent = (Button)view.findViewById(R.id.percent);
        dot = (Button)view.findViewById(R.id.dot);
        double_zero = (Button)view.findViewById(R.id.double_zero);
        equal = (Button)view.findViewById(R.id.equal);
        one.setOnClickListener(this);
        two.setOnClickListener(this);
        three.setOnClickListener(this);
        four.setOnClickListener(this);
        five.setOnClickListener(this);
        six.setOnClickListener(this);
        seven.setOnClickListener(this);
        eight.setOnClickListener(this);
        nine.setOnClickListener(this);
        zero.setOnClickListener(this);
        plus.setOnClickListener(this);
        subtract.setOnClickListener(this);
        divide.setOnClickListener(this);
        multiply.setOnClickListener(this);
        plusMinus.setOnClickListener(this);
        divide.setText(Html.fromHtml(Helper.division));
        plusMinus.setText(Html.fromHtml(Helper.plusMinus));
        ac.setOnClickListener(this);
        percent.setOnClickListener(this);
        dot.setOnClickListener(this);
        double_zero.setOnClickListener(this);
        equal.setOnClickListener(this);
        return view;
    }
    private void obtainInputValues(String input){
        switch (input){
            case "0":
                currentDisplayedInput += "0";
                inputToBeParsed += "0";
                break;
            case "1":
                currentDisplayedInput += "1";
                inputToBeParsed += "1";
                break;
            case "2":
                currentDisplayedInput += "2";
                inputToBeParsed += "2";
                break;
            case "3":
                currentDisplayedInput += "3";
                inputToBeParsed += "3";
                break;
            case "4":
                currentDisplayedInput += "4";
                inputToBeParsed += "4";
                break;
            case "5":
                currentDisplayedInput += "5";
                inputToBeParsed += "5";
                break;
            case "6":
                currentDisplayedInput += "6";
                inputToBeParsed += "6";
                break;
            case "7":
                currentDisplayedInput += "7";
                inputToBeParsed += "7";
                break;
            case "8":
                currentDisplayedInput += "8";
                inputToBeParsed += "8";
                break;
            case "9":
                currentDisplayedInput += "9";
                inputToBeParsed += "9";
                break;
            case ".":
                currentDisplayedInput += ".";
                inputToBeParsed += ".";
                break;
            case "+":
                currentDisplayedInput += "+";
                inputToBeParsed += "+";
                break;
            case "-":
                currentDisplayedInput += "-";
                inputToBeParsed += "-";
                break;
            case "/":
                currentDisplayedInput += "/";
                inputToBeParsed += "/";
                break;
            case "x":
                currentDisplayedInput += "*";
                inputToBeParsed += "*";
                break;
            case "%":
                currentDisplayedInput += "%";
                inputToBeParsed += "%";
                break;
            case "00":
                currentDisplayedInput += "00";
                inputToBeParsed += "00";
                break;
            case "=":
                currentDisplayedInput += "00";
                inputToBeParsed += "00";
                break;
        }
        outputResult.setText(currentDisplayedInput);
    }
    @Override
    public void onClick(View view) {
        Button button = (Button) view;
        String data = button.getText().toString();
        Toast.makeText(getContext(), "Click " + data, Toast.LENGTH_LONG).show();
        if(data.equals("AC")){
            outputResult.setText("");
            currentDisplayedInput = "";
            inputToBeParsed = "";
        }
        else if(data.equals("=")){
            String enteredInput = outputResult.getText().toString();
            // call a function that will return the result of the calculate.
            String resultObject = mCalculator.getResult(currentDisplayedInput, inputToBeParsed);
            outputResult.setText(removeTrailingZero(resultObject));
        }
        else{
            obtainInputValues(data);
        }
    }
    private String removeTrailingZero(String formattingInput){
        if(!formattingInput.contains(".")){
            return formattingInput;
        }
        int dotPosition = formattingInput.indexOf(".");
        String newValue = formattingInput.substring(dotPosition, formattingInput.length());
        if(newValue.equals(".0")){
            return formattingInput.substring(0, dotPosition);
        }
        return formattingInput;
    }
}

We will look into our parse class now. There are many libraries out there but we are going to use Javalutor. Add this library to your application. If you don’t know how to add java third-party library to your project, I will suggest that you read one of my tutorial on this topic.

I adopted the Math Parse class using the Javalutor library from here, although I have modify the class to suit our own need. The Calculator class parse code is shown below. Create this class in your application and copy and paste the below code in it.

import com.fathzer.soft.javaluator.DoubleEvaluator;
import com.fathzer.soft.javaluator.Function;
import com.fathzer.soft.javaluator.Parameters;
import java.util.ArrayList;
import java.util.Iterator;

public class Calculator {
    // The function has one argument and its name is "sqrt"
    final Function sqrt = new Function("sqrt", 1);
    final Function factorial = new Function("!", 1);
    final Function cuberoot = new Function("crt", 1);
    final Function combination = new Function("comb", 2);
    final Function permutation = new Function("permu", 2);
    Parameters params;
    DoubleEvaluator evaluator;
    private double previousSum = 0;
    private double currentSum = 0;
    private String currentDisplay = "";
    //private String expressionUsedForParsing ="";
    private boolean isRadians = false;
    public Calculator() {
        addFunctions();
        //Adds the functions to the evaluator
        evaluator = new DoubleEvaluator(params) {
            @Override
            protected Double evaluate(Function function, Iterator arguments, Object evaluationContext) {
                if (function == sqrt)
                    return Math.sqrt((Double) arguments.next());
                else if(function == cuberoot){
                    return Math.cbrt((Double) arguments.next());
                }
                else if(function == combination){
                    double numberInputs = 0;
                    ArrayList<Double> saveValue = new ArrayList<Double>();
                    while(arguments.hasNext()) {
                        numberInputs = (Double) arguments.next();
                        saveValue.add(numberInputs);
                    }
                    double firstArgument = saveValue.get(0);
                    double secondArgument = saveValue.get(1);
                    double denominator = getFactorial((int) firstArgument);
                    double nominator = getFactorial((int)secondArgument) * (getFactorial((int)(firstArgument - secondArgument)));
                    return denominator / nominator;
                }
                else if(function == permutation){
                    double numberInputs = 0;
                    ArrayList<Double> saveValue = new ArrayList<Double>();
                    while(arguments.hasNext()) {
                        numberInputs = (Double) arguments.next();
                        saveValue.add(numberInputs);
                    }
                    double firstArgument = saveValue.get(0);
                    double secondArgument = saveValue.get(1);
                    double denominator = getFactorial((int) firstArgument);
                    double nominator = (getFactorial((int)(firstArgument - secondArgument)));
                    return denominator / nominator;
                }
                else if (function == factorial) {
                    double result = 1;
                    double num = (Double) arguments.next();
                    for (int i = 2; i <= num; i++) {
                        result = result * i;
                    }
                    return result;
                } else
                    return super.evaluate(function, arguments, evaluationContext);
            }
        };
    }
    private int getFactorial(int n)    {
        int result;
        if(n==0 || n==1)
            return 1;
        result = getFactorial(n-1) * n;
        return result;
    }
    public void addFunctions() {
        params = DoubleEvaluator.getDefaultParameters();
        params.add(sqrt);
        params.add(factorial);
        params.add(cuberoot);
        params.add(combination);
        params.add(permutation);
    }
    public String getResult(String currentDisplay, String expressionUsedForParsing) {
        //Tries to parse the information as it is entered, if the parser can't handle it, the word error is shown on screen
        try {
            System.out.println("Displayed Output " + expressionUsedForParsing);
            currentSum = evaluator.evaluate(fixExpression(expressionUsedForParsing));
            currentSum = convertToRadians(currentSum);
            currentDisplay = String.valueOf(currentSum);
            //previousSum = currentSum;
        } catch (Exception e) {
            currentDisplay = "Error";
        }
        return currentDisplay;
    }
    public double convertToRadians(double sum){
        double newSum = sum;
        if(isRadians == true)
            newSum = Math.toRadians(sum);
        return newSum;
    }
    //Used to show display to user
    public String getCurrentDisplay() {
        return currentDisplay;
    }
    //Handles fixing the expression before parsing. Adding parens, making sure parens can multiply with each other,
    public String fixExpression(String exp) {
        int openParens = 0;
        int closeParens = 0;
        char openP = '(';
        char closeP = ')';
        String expr = exp;
        for (int i = 0; i < exp.length(); i++) {
            if (exp.charAt(i) == openP)
                openParens++;
            else if (exp.charAt(i) == closeP)
                closeParens++;
        }
        while (openParens > 0) {
            expr += closeP;
            openParens--;
        }
        while (closeParens > 0) {
            expr = openP + expr;
            closeParens--;
        }
        expr = multiplicationForParens(expr);
        return expr;
    }
    //Used to fix multiplication between parentheses
    public String multiplicationForParens(String s) {
        String fixed = "";
        for (int position = 0; position < s.length(); position++) {
            fixed += s.charAt(position);
            if (position == s.length() - 1)
                continue;
            if (s.charAt(position) == ')' && s.charAt(position + 1) == '(')
                fixed += '*';
            if (s.charAt(position) == '(' && s.charAt(position + 1) == ')')
                fixed += '1';
        }
        return fixed;
    }
}

This brings us to the end of this tutorial, If you find anything confusing kindly contact me with your questions or use the comment box below.

Now, when you run your application you will see the interface that looks similar to the sample that was shown earlier on.

You can download the code for this tutorial below. If you are having hard time downloading the tutorials, kindly contact me.

Remember to subscribe with your email so that you will be among the first to receive our new post once it is published.

If you like this tutorial, you can see the Scientific Calculator in action in my Complete Mathematics App in Google Play Store. You are free to use and modify the source code for your own use.

8 Comments

    • Inducesmile

Add a Comment