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();
}
}
HOW TO DOWNLOAD THE COMPLETE SOURCE CODE
You can follow this tutorial and complete the tutorial with the code snippets provided in the tutorial.
The source code is not free to download because we spent a lot of time to create these apps from scratch and your little donation will help us to even create more apps from scratch.
SUMMARY
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.