How to build Android Calculator App

In this episode of how to build mobile app from scratch, we are going to build a simple android calculator.

Lets start with the initial taught process we encounter whenever we need to build a mobile.

Is there a need to use a third-party libraries in our app development?

Good third party libraries are life savers in software development. As the sayings go, there is no need to reinvent the wheels. Libraries can save us development time and money.

Although, simple android calculator application can be build without a library but in this tutorial, we will use a Java Math Equation Parse named MathParser

How would the user interface of the calculator app looks like?

In as much as we want to build a simple android calculator app, we should have it in mind that our design should be sleek and the app must be easy to use.

First, I usually research a bit on other similar app and try to get inspiration from existing apps.

Below is one of the hand sketches I made in order to have a clear overview about the app I plan to build.

What is the best color combination to use in order to get the app core message across?

Matching colors has always been challenging to me. I do not have an art background so I usually relay on my intuition.

Feel free to choose combination of colors that will make your app stand out in the crowd.

Android Calculator App Screenshot

1. Create New Android Project

  • Open Android Studio
  • Go to file menu
  • Select  new
  • Enter project name 
  • Enter activity name
  • Keep other default settings
  • Click on finish button to create a new android project

2. Add library dependencies in build.gradle

Open the build.gradle module file and add the code below in the dependencies section. 

implementation files('libs/MathParser.org-mXparser-v.4.2.0-jdk.1.7.jar')
implementation 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'

3. Update colors.xml

Open res folder > strings.xml and add the code below to it.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#008577</color>
    <color name="colorPrimaryDark">#00574B</color>
    <color name="colorAccent">#D81B60</color>
    <color name="colorWhite">#ffffff</color>
    <color name="colorBlack">#000000</color>
    <color name="colorAsh">#bbb</color>
    <color name="colorBg">#03A8FF</color>
</resources>

4. Update styles.xml

Open res folder > styles.xml and add the code below to it.

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

    <style name="AppTheme.NoActionBar">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
        <item name="android:windowActionBarOverlay">true</item>
        <item name="windowActionBarOverlay">true</item>
    </style>

    <style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />

    <style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />

    <style name="stylish">
        <item name="android:layout_width">0dp</item>
        <item name="android:layout_height">60dp</item>
        <item name="android:layout_weight">1</item>
        <item name="android:gravity">center</item>
        <item name="android:textColor">@android:color/white</item>
        <item name="android:textSize">30sp</item>
        <item name="android:fontFamily">@font/google_sans_family</item>
        <item name="android:background">?attr/selectableItemBackground</item>
    </style>

    <style name="arithmetic_keys" parent="stylish">
        <item name="android:textColor">@android:color/holo_red_light</item>
    </style>

    <style name="foto_vertical_views">
        <item name="android:layout_width">0dp</item>
        <item name="android:layout_height">60dp</item>
        <item name="android:layout_weight">0.01</item>
        <item name="android:background">@android:color/black</item>
    </style>

    <style name="CalculatorTextView">
        <item name="android:layout_width">0dp</item>
        <item name="android:layout_height">0dp</item>
        <item name="android:gravity">center</item>
        <item name="android:textSize">30sp</item>
        <item name="android:fontFamily">@font/google_sans_family</item>
        <item name="android:background">?attr/selectableItemBackground</item>
    </style>

</resources>

5. MainActivity.java

In the MainActivity class, we will make the page full-screen and add an Image and text views to its layout file.

We used Handle class postDelayed() method to add a 2 seconds delay before we navigate to the calculator page.

Open MainActivity class and add the code below to it

import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;

public class MainActivity extends AppCompatActivity {

    private static final String TAG = MainActivity.class.getSimpleName();

    private static final int SPLASH_TIME = 2000;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

        super.onCreate(savedInstanceState);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
            getWindow().setStatusBarColor(Color.TRANSPARENT);
        }

        setContentView(R.layout.activity_main);

        ActionBar actionBar = getSupportActionBar();
        if(null != actionBar){
            actionBar.hide();
        }

        Handler handler = new Handler();
        handler.postDelayed(() -> {
            Intent intent = new Intent(MainActivity.this, SimpleCalculatorActivity.class);
            startActivity(intent);
            finish();
        }, SPLASH_TIME);
    }
}

6. activity_main.xml

Go to activity_main.xml and add the code below to it.

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
    android:background="@color/colorBg"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:orientation="vertical"
        android:gravity="center"
        android:padding="20dp"
        tools:ignore="UseCompoundDrawables">

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/calculator_logo"
            android:contentDescription="@string/app_name"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Simple Calculator"
            android:textColor="@color/colorBlack"
            android:layout_marginTop="10dp"
            android:textSize="14sp"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="12sp"
            android:layout_marginTop="4dp"
            android:textColor="@color/colorAsh"
            android:text="From Inducesmile.com"/>

    </LinearLayout>

</FrameLayout>

7. Create a new activity 

Right click on your package folder > new > empty activity. In the open activity creation dialog, add the name of your activity. 

I named mineSimpleCalculatorActivity.java. Free feel to choose a name of your choice.

8. activity_simple_calculator.xml

Open the activity_simple_calculator.xml file, we will use android constraint layout to position the views we need to create our calculator interface.

The layout code is very simple and easy to understand. 

Add the code below to the layout file. Use Android Studio layout preview to check that the layout components are well fitted as intended.

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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=".SimpleCalculatorActivity">

    <View
        android:id="@+id/view"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="@color/colorBg"
        app:layout_constraintBottom_toTopOf="@+id/scrollView2"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/result_tv"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_marginTop="8dp"
        android:layout_weight="2"
        android:fontFamily="@font/google_sans_family"
        android:gravity="end|center"
        android:maxLines="1"
        android:padding="8dp"
        android:textColor="@color/colorWhite"
        android:textSize="60sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/toggle_nav"
        tools:text="0" />

    <TextView
        android:id="@+id/keys_pressed_tv"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:fontFamily="@font/google_sans_family"
        android:gravity="end|center"
        android:maxLines="1"
        android:padding="8dp"
        android:textColor="@color/colorWhite"
        android:textSize="40sp"
        android:scrollHorizontally="true"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/result_tv"
        tools:text="0" />

    <ScrollView
        android:id="@+id/scrollView2"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:fillViewport="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/keys_pressed_tv">

        <android.support.constraint.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <android.support.constraint.Guideline
                android:id="@+id/guideline"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                app:layout_constraintGuide_percent="0.25" />

            <android.support.constraint.Guideline
                android:id="@+id/guideline3"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                app:layout_constraintGuide_percent="0.75" />

            <android.support.constraint.Guideline
                android:id="@+id/guideline2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                app:layout_constraintGuide_percent="0.5" />

            <android.support.constraint.Guideline
                android:id="@+id/guideline4"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="horizontal"
                app:layout_constraintGuide_percent="0.20" />

            <android.support.constraint.Guideline
                android:id="@+id/guideline5"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="horizontal"
                app:layout_constraintGuide_percent="0.40" />

            <android.support.constraint.Guideline
                android:id="@+id/guideline6"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="horizontal"
                app:layout_constraintGuide_percent="0.60" />

            <android.support.constraint.Guideline
                android:id="@+id/guideline7"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="horizontal"
                app:layout_constraintGuide_percent="0.80" />

            <TextView
                android:id="@+id/key_percentage"
                style="@style/CalculatorTextView"
                android:text="%"
                app:layout_constraintBottom_toTopOf="@+id/guideline4"
                app:layout_constraintEnd_toStartOf="@+id/guideline"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />

            <TextView
                android:id="@+id/key_open_bracket"
                style="@style/CalculatorTextView"
                android:text="("
                app:layout_constraintBottom_toTopOf="@+id/guideline4"
                app:layout_constraintEnd_toStartOf="@+id/guideline2"
                app:layout_constraintStart_toStartOf="@+id/guideline"
                app:layout_constraintTop_toTopOf="parent" />

            <TextView
                android:id="@+id/key_close_bracket"
                style="@style/CalculatorTextView"
                android:text=")"
                app:layout_constraintBottom_toTopOf="@+id/guideline4"
                app:layout_constraintEnd_toStartOf="@+id/guideline3"
                app:layout_constraintStart_toStartOf="@+id/guideline2"
                app:layout_constraintTop_toTopOf="parent" />

            <TextView
                android:id="@+id/key_divide_operation"
                style="@style/CalculatorTextView"
                android:text="÷"
                app:layout_constraintBottom_toTopOf="@+id/guideline4"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="@+id/guideline3"
                app:layout_constraintTop_toTopOf="parent" />

            <TextView
                android:id="@+id/key_seven"
                style="@style/CalculatorTextView"
                android:text="7"
                app:layout_constraintBottom_toTopOf="@+id/guideline5"
                app:layout_constraintEnd_toStartOf="@+id/guideline"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="@+id/guideline4" />

            <TextView
                android:id="@+id/key_eight"
                style="@style/CalculatorTextView"
                android:text="8"
                app:layout_constraintBottom_toTopOf="@+id/guideline5"
                app:layout_constraintEnd_toStartOf="@+id/guideline2"
                app:layout_constraintStart_toStartOf="@+id/guideline"
                app:layout_constraintTop_toTopOf="@+id/guideline4" />

            <TextView
                android:id="@+id/key_nine"
                style="@style/CalculatorTextView"
                android:text="9"
                app:layout_constraintBottom_toTopOf="@+id/guideline5"
                app:layout_constraintEnd_toStartOf="@+id/guideline3"
                app:layout_constraintStart_toStartOf="@+id/guideline2"
                app:layout_constraintTop_toTopOf="@+id/guideline4" />

            <TextView
                android:id="@+id/key_multiply_operation"
                style="@style/CalculatorTextView"
                android:layout_marginBottom="8dp"
                android:layout_marginEnd="8dp"
                android:layout_marginStart="8dp"
                android:layout_marginTop="8dp"
                android:text="x"
                app:layout_constraintBottom_toTopOf="@+id/guideline5"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="@+id/guideline3"
                app:layout_constraintTop_toTopOf="@+id/guideline4" />

            <TextView
                android:id="@+id/key_four"
                style="@style/CalculatorTextView"
                android:text="4"
                app:layout_constraintBottom_toTopOf="@+id/guideline6"
                app:layout_constraintEnd_toStartOf="@+id/guideline"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="@+id/guideline5" />

            <TextView
                android:id="@+id/key_five"
                style="@style/CalculatorTextView"
                android:text="5"
                app:layout_constraintBottom_toTopOf="@+id/guideline6"
                app:layout_constraintEnd_toStartOf="@+id/guideline2"
                app:layout_constraintStart_toStartOf="@+id/guideline"
                app:layout_constraintTop_toTopOf="@+id/guideline5" />

            <TextView
                android:id="@+id/key_six"
                style="@style/CalculatorTextView"
                android:text="6"
                app:layout_constraintBottom_toTopOf="@+id/guideline6"
                app:layout_constraintEnd_toStartOf="@+id/guideline3"
                app:layout_constraintStart_toStartOf="@+id/guideline2"
                app:layout_constraintTop_toTopOf="@+id/guideline5" />

            <TextView
                android:id="@+id/key_subtract_operation"
                style="@style/CalculatorTextView"
                android:text="-"
                app:layout_constraintBottom_toTopOf="@+id/guideline6"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="@+id/guideline3"
                app:layout_constraintTop_toTopOf="@+id/guideline5" />

            <TextView
                android:id="@+id/key_one"
                style="@style/CalculatorTextView"
                android:text="1"
                app:layout_constraintBottom_toTopOf="@+id/guideline7"
                app:layout_constraintEnd_toStartOf="@+id/guideline"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="@+id/guideline6" />

            <TextView
                android:id="@+id/key_two"
                style="@style/CalculatorTextView"
                android:text="2"
                app:layout_constraintBottom_toTopOf="@+id/guideline7"
                app:layout_constraintEnd_toStartOf="@+id/guideline2"
                app:layout_constraintStart_toStartOf="@+id/guideline"
                app:layout_constraintTop_toTopOf="@+id/guideline6" />

            <TextView
                android:id="@+id/key_three"
                style="@style/CalculatorTextView"
                android:text="3"
                app:layout_constraintBottom_toTopOf="@+id/guideline7"
                app:layout_constraintEnd_toStartOf="@+id/guideline3"
                app:layout_constraintStart_toStartOf="@+id/guideline2"
                app:layout_constraintTop_toTopOf="@+id/guideline6" />

            <TextView
                android:id="@+id/key_addition_operation"
                style="@style/CalculatorTextView"
                android:text="+"
                app:layout_constraintBottom_toTopOf="@+id/guideline7"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="@+id/guideline3"
                app:layout_constraintTop_toTopOf="@+id/guideline6" />

            <TextView
                android:id="@+id/key_zero"
                style="@style/CalculatorTextView"
                android:text="0"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toStartOf="@+id/guideline"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="@+id/guideline7" />

            <TextView
                android:id="@+id/key_dot"
                style="@style/CalculatorTextView"
                android:text="."
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toStartOf="@+id/guideline2"
                app:layout_constraintStart_toStartOf="@+id/guideline"
                app:layout_constraintTop_toTopOf="@+id/guideline7" />

            <TextView
                android:id="@+id/key_submission_operation"
                style="@style/CalculatorTextView"
                android:text="="
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="@+id/guideline3"
                app:layout_constraintTop_toTopOf="@+id/guideline7" />

            <TextView
                android:id="@+id/key_delete"
                style="@style/CalculatorTextView"
                android:text="⌫"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toStartOf="@+id/key_submission_operation"
                app:layout_constraintStart_toStartOf="@+id/guideline2"
                app:layout_constraintTop_toBottomOf="@+id/key_three" />

            <TextView
                android:id="@+id/clear_tv"
                style="@style/CalculatorTextView"
                android:text="CLS"
                android:visibility="invisible"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toStartOf="@+id/guideline3"
                app:layout_constraintStart_toStartOf="@+id/key_delete"
                app:layout_constraintTop_toTopOf="@+id/key_delete" />

        </android.support.constraint.ConstraintLayout>

    </ScrollView>

    <android.support.constraint.Guideline
        android:id="@+id/guideline8"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_begin="20dp" />

    <android.support.constraint.Guideline
        android:id="@+id/guideline9"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_begin="20dp" />

    <ImageView
        android:id="@+id/toggle_nav"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_menu"
        app:layout_constraintStart_toStartOf="@+id/guideline8"
        app:layout_constraintTop_toTopOf="@+id/guideline9" />

    <android.support.constraint.Guideline
        android:id="@+id/guideline10"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_end="20dp" />

    <ImageView
        android:id="@+id/imageView3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_open_in_new"
        app:layout_constraintEnd_toStartOf="@+id/guideline10"
        app:layout_constraintTop_toTopOf="@+id/guideline9" />

</android.support.constraint.ConstraintLayout>

9. SimpleCalculatorActivity.java

Remember in the beginning we added some android libraries that will help us speed up our development process. 

If you have not used a View Binder library before in android, I will suggestion you read my tutorial on Android Butter Knife Tutorial

We will use ButterKnife library to instantiate our button view and add click event listener to them.

ButterKnife makes our code looks simple and easy to understand. It also removes boilerplate codes like findViewById and setOnClickListener which would have clustered our class.

Finally, we use the Expression class and calculate method from the MathParse library to evaluate user input and display the result on the screen.

Open the SimpleCalculatorActivity class and add the code below.

import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.TextView;

import org.mariuszgromada.math.mxparser.Expression;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.Unbinder;

public class SimpleCalculatorActivity extends AppCompatActivity {

    Unbinder unbinder;

    @BindView(R.id.result_tv)
    TextView resultTv;

    @BindView(R.id.keys_pressed_tv)
    TextView keysPressedTv;

    @BindView(R.id.key_delete)
    TextView mDeleteTv;

    @BindView(R.id.clear_tv)
    TextView mClearTv;

    private static String TAG = SimpleCalculatorActivity.class.getSimpleName();
    private String text = "";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_simple_calculator);

        ActionBar actionBar = getSupportActionBar();
        if(null != actionBar){
            actionBar.hide();
        }

        unbinder = ButterKnife.bind(this);
        resultTv.setText("0");
    }



    @OnClick(R.id.key_seven)
    public void clickedSeven() {
        if (containsLastLetter("%"))
            keysPressedTv.setText(keysPressedTv.getText()+ "x7");
        else
            keysPressedTv.setText(keysPressedTv.getText() + "7");
        carryOutCalculation();
    }

    @OnClick(R.id.key_percentage)
    public void percentClicked() {
        if (!keysPressedTv.getText().toString().equals("")) {
            if (!containsLastLetter("%"))
                keysPressedTv.setText(keysPressedTv.getText() + "%");
            carryOutCalculation();
        }
    }

    @OnClick(R.id.key_open_bracket)
    public void openBracketClicked() {
        if (keysPressedTv.getText().toString().equals("")) {
            keysPressedTv.setText(keysPressedTv.getText() + "(");
            return;
        }
        if (!containsLastLetter("+") && !containsLastLetter("-") &&
                !containsLastLetter("x") && !containsLastLetter("÷")) {
            keysPressedTv.setText(keysPressedTv.getText() + "x(");
            return;
        }

        if (!containsLastLetter("(")) {
            keysPressedTv.setText(keysPressedTv.getText() + "(");
            return;
        }
    }

    @OnClick(R.id.key_close_bracket)
    public void closeBracketClicked() {
        if (!keysPressedTv.getText().toString().equals("")) {
            if (!containsLastLetter(")") || !containsLastLetter("("))
                keysPressedTv.setText(keysPressedTv.getText() + ")");
            carryOutCalculation();
        }
    }

    @OnClick(R.id.key_divide_operation)
    public void divideClicked() {
        if (!keysPressedTv.getText().toString().equals("")) {
            if (!containsLastLetter("÷"))
                operatorClicked("÷");
        }
    }

    private void operatorClicked(String operator) {
        if (mClearTv.getVisibility() == View.VISIBLE && resultTv.getText().toString() != "Error") {
            keysPressedTv.setText(resultTv.getText().toString() + operator);
            mDeleteTv.setVisibility(View.VISIBLE);
            mClearTv.setVisibility(View.GONE);
        } else
            keysPressedTv.setText(keysPressedTv.getText() + operator);
    }

    @OnClick(R.id.key_eight)
    public void eightClicked() {
        if (containsLastLetter("%"))
            keysPressedTv.setText(keysPressedTv.getText()+ "x8");
        else
            keysPressedTv.setText(keysPressedTv.getText() + "8");
        carryOutCalculation();
    }

    @OnClick(R.id.key_nine)
    public void nineClicked() {
        if (containsLastLetter("%"))
            keysPressedTv.setText(keysPressedTv.getText()+ "x9");
        else
            keysPressedTv.setText(keysPressedTv.getText() + "9");
        carryOutCalculation();
    }

    @OnClick(R.id.key_multiply_operation)
    public void multiplyClicked() {

        if (!keysPressedTv.getText().toString().equals("")) {
            if (!containsLastLetter("x"))
                operatorClicked("x");
        }
    }

    @OnClick(R.id.key_four)
    public void fourClicked() {
        if (containsLastLetter("%"))
            keysPressedTv.setText(keysPressedTv.getText()+ "x4");
        else
            keysPressedTv.setText(keysPressedTv.getText() + "4");
        carryOutCalculation();
    }

    @OnClick(R.id.key_five)
    public void fivePressed() {
        if (containsLastLetter("%"))
            keysPressedTv.setText(keysPressedTv.getText()+ "x5");
        else
            keysPressedTv.setText(keysPressedTv.getText() + "5");
        carryOutCalculation();
    }

    @OnClick(R.id.key_six)
    public void sixClicked() {
        if (containsLastLetter("%"))
            keysPressedTv.setText(keysPressedTv.getText()+ "x6");
        else
            keysPressedTv.setText(keysPressedTv.getText() + "6");
        carryOutCalculation();
    }

    @OnClick(R.id.key_subtract_operation)
    public void subtractClicked() {
        if (keysPressedTv.getText().toString().equals("")) {
            keysPressedTv.setText(keysPressedTv.getText() + "-");
            return;
        }
        if (!containsLastLetter("-"))
            operatorClicked("-");
    }

    @OnClick(R.id.key_one)
    public void oneClicked() {
        if (containsLastLetter("%"))
            keysPressedTv.setText(keysPressedTv.getText()+ "x1");
        else
            keysPressedTv.setText(keysPressedTv.getText() + "1");
        carryOutCalculation();
    }

    @OnClick(R.id.key_two)
    public void twoClicked() {
        if (containsLastLetter("%"))
            keysPressedTv.setText(keysPressedTv.getText()+ "x2");
        else
            keysPressedTv.setText(keysPressedTv.getText() + "2");
        carryOutCalculation();
    }

    @OnClick(R.id.key_three)
    public void threeClicked() {
        if (containsLastLetter("%"))
            keysPressedTv.setText(keysPressedTv.getText()+ "x3");
        else
            keysPressedTv.setText(keysPressedTv.getText() + "3");
        carryOutCalculation();
    }

    @OnClick(R.id.key_addition_operation)
    public void addClicked() {
        if (!keysPressedTv.getText().toString().equals("")) {
            if (!containsLastLetter("+"))
                operatorClicked("+");
        }
    }

    @OnClick(R.id.key_zero)
    public void zeroClicked() {
        keysPressedTv.setText(keysPressedTv.getText() + "0");
        carryOutCalculation();
    }

    @OnClick(R.id.key_dot)
    public void dotClicked() {
        if (!keysPressedTv.getText().toString().equals("")) {
            if (!containsLastLetter(".")) {
                keysPressedTv.setText(keysPressedTv.getText() + ".");
            }
        }
    }

    public boolean containsLastLetter(String letter) {
        String text = keysPressedTv.getText().toString();
        String last = "";
        if(text.length() != 0)
            last = text.substring(text.length() - 1);
        return last.equals(letter);
    }

    @OnClick(R.id.key_delete)
    public void deleteClicked() {
        deleteKeyClicked();
    }

    @OnClick(R.id.clear_tv)
    public void clear() {
        keysPressedTv.setText("");
        resultTv.setText("0");
        mDeleteTv.setVisibility(View.VISIBLE);
        mClearTv.setVisibility(View.INVISIBLE);
    }

    @OnClick(R.id.key_submission_operation)
    public void submit() {
        carryOutCalculation();
        mClearTv.setVisibility(View.VISIBLE);
        mDeleteTv.setVisibility(View.INVISIBLE);
    }

    private void deleteKeyClicked() {
        text = keysPressedTv.getText().toString();
        if (text.length() > 0) {

            String newText = text.substring(0, text.length() - 1);

            if (newText.equals("-")) {
                newText = "";
            }

            keysPressedTv.setText(newText);

            if (!newText.isEmpty()) {
                String last = newText.substring(newText.length() - 1);
            } else {
                resultTv.setText("0");
            }
        }
    }

    private void carryOutCalculation() {
        String expression = keysPressedTv.getText().toString();


        if (expression.contains("x")) {
            expression = expression.replace("x", "*");
        }

        if (expression.contains("÷")) {
            expression = expression.replace("÷", "/");
        }

        if (expression.contains("(") && !expression.substring(expression.lastIndexOf("("), expression.length()).contains(")")) {
            expression += ")";
        }

        Log.d(TAG, expression);

        //Carry out the calculation
        Expression e1 = new Expression(expression);
        String answer = String.valueOf(e1.calculate());

        //Format Error
        if (answer.equals("NaN"))
            answer = "Error";

        resultTv.setText(answer);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbinder.unbind();
    }
}

This brings us to the end of how to build android calculator from scratch.

If you have any question with regards to this project kindly use the comment box below and do let us know.

Do you have any project in mind that you will like us to build, kindly notify us below.

Please note that it might not happen immediately since there are other projects we have schedule to do.

Add a Comment