It is a simple calculator app. I made it for studying Android.
Android Studio 3.6.2 TableLayout
-Create a button that straddles columns in TableLayout Nested LinearLayout inside the Table row.
・ Display images only under specific conditions Changed to set the image in imageView with setImageResource.
・ Processing that prioritizes multiplication and division Store the calculation formula in ArrayList → Search for × ÷ and perform priority calculation → Delete the calculated part from the list → Add the calculation result to the list → Repeat until × ÷ disappears → Then perform + -calculation I implemented it by the method.
・ Lose the calculation error of double The problem that "1.0d --0.9d = 0.099999999 ..." is displayed. I solved it using the BigDecimal class.
・ An error will occur when the division is not divisible. BigDecimal causes an ArithmeticException when a number that is not divisible by division (recurring decimal) appears. To avoid this error, the number with 11 decimal places is rounded off. However, this time, there is a problem that even when the number is divisible, it is displayed up to the 10th decimal place. It will be like this → 4/2 = 2.0000000000 To avoid this, the division is enclosed in try-catch and the number with 11 decimal places is rounded only when an ArithmeticException occurs.
・ Bug fix Avoid typing multiple decimal points. Do not hit +-× ÷ = in an unintended place. = Various behaviors after clicking the button. There were many other things ...
Nest the LinearLayout inside the Table row.
activity_main.xml
<TableRow
android:id="@+id/row2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="2">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/button4"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="@string/button4"
android:textSize="25sp"
android:onClick="btnCurrent_onClick"/>
<Button
android:id="@+id/button1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="@string/button1"
android:textSize="25sp"
android:onClick="btnCurrent_onClick"/>
</LinearLayout>
<!--Button across lines-->
<Button
android:id="@+id/buttonPlus"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:background="#FFBF00"
android:text="@string/buttonPlus"
android:textSize="25sp"
android:onClick="btnCurrent_onClick"/>
</TableRow>
I learned a lot because I couldn't understand until I made it. I will continue to learn in the cycle of reading a book → trying to make it.
The point of reflection is that it is full of if statements. I want to write cleaner code.
MainActivity.java
package to.msn.wings.caluculator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Bundle;
import android.text.Editable;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
List<String> stringList = new ArrayList<>();//List to store input characters
int decimalPointCount = 0; //Variable to prevent continuous clicks on the decimal point button.
int ClickedFormulaOnce = 0; // +-/*For determining whether even one is included in the calculation formula.+-*/Because it cannot be calculated without even one.
int formulaContinuousClick = 0; // +-/*Variable to prevent continuous clicks on the button.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
//Calculation method
public void calculation(TextView txt) {
//Get all the characters of TextView and store them in the array.
String txtAll = txt.getText().toString();
//Regular expression that also includes the delimiter itself in the array
//Regular expressions((?<=[+×÷-])|(?=[+×÷-]))The meaning of+-It means to separate immediately before and after × ÷.
String[] stringArray = txtAll.split("((?<=[+×÷-])|(?=[+×÷-]))", 0);
//After storing in the array, delete all the characters in TextView.
txt.setText(null);
//Store all arrays in ArrayList.
for(String s:stringArray) {
stringList.add(s);
}
//Big Decimal has no error unlike double.
BigDecimal bigDecimalResultValue = new BigDecimal("0.0");
//Multiplication division processing
for(int i = 1; i < stringList.size(); i += 2) {
if(stringList.get(i).equals("×")) {
bigDecimalResultValue = new BigDecimal(stringList.get(i-1)).multiply(new BigDecimal(stringList.get(i+1)));
//Remove the calculated numbers and expressions from the stringList. Example: "2*3+"2" of "1"*Delete the part of "3".
stringList.remove(i-1);
stringList.remove(i-1);
stringList.remove(i-1);
//Add the calculation result to stringList. Example: "2*3+1 "to" 6+Set to 1 ".
stringList.add(i-1, String.valueOf(bigDecimalResultValue));
//Since we deleted 3 stringLists and added 1 to them, subtract 2 from i.
i -= 2;
} else if (stringList.get(i).equals("÷")) {
//When the division of Bigdecimal is an indivisible number, an ArithmeticException error occurs. Therefore, enclose it in trycath.
//When this is finally divisible, 00000 is not wasted after the decimal point.
//Round the 11th decimal place only when it is not divisible.
try {
bigDecimalResultValue = new BigDecimal(stringList.get(i-1)).divide(new BigDecimal(stringList.get(i+1)));
} catch (ArithmeticException e) {
bigDecimalResultValue = new BigDecimal(stringList.get(i-1)).divide(new BigDecimal(stringList.get(i+1)), 10, RoundingMode.HALF_UP);//Rounded. Display up to 10 decimal places.
}
stringList.remove(i-1);
stringList.remove(i-1);
stringList.remove(i-1);
stringList.add(i-1, String.valueOf(bigDecimalResultValue));
i -= 2;
}
}
//Addition and subtraction processing
//Multiplication and division have already been processed, so simply add and subtract in order from the front.
while(stringList.size() > 1) {
if(stringList.get(1).equals("+")) {
bigDecimalResultValue = new BigDecimal(stringList.get(0)).add(new BigDecimal(stringList.get(2)));
stringList.remove(0);
stringList.remove(0);
stringList.remove(0);
stringList.add(0, String.valueOf(bigDecimalResultValue));
} else if (stringList.get(1).equals("-")) {
bigDecimalResultValue = new BigDecimal(stringList.get(0)).subtract(new BigDecimal(stringList.get(2)));
stringList.remove(0);
stringList.remove(0);
stringList.remove(0);
stringList.add(0, String.valueOf(bigDecimalResultValue));
}
}
if(String.valueOf(bigDecimalResultValue).equals("3")) {
//Processing to display the image only when the result is 3
//Get ImageView object based on ID
@SuppressLint("ResourceType")
ImageView iv = this.findViewById(R.id.imageView);
//Set the image in the drawable folder
iv.setImageResource(R.drawable.nabeatsu);
txt.setText("World pans");
} else {
txt.setText(String.valueOf(bigDecimalResultValue));
}
//Clear the list after displaying the results.
stringList.clear();
}
public void btnCurrent_onClick(View view) {
//Get text view
TextView txt = findViewById(R.id.textView);
//Judge the button clicked by the switch statement. Display in text.
switch (view.getId()) {
case R.id.button0:
txt.append("0");
formulaContinuousClick = 0;
break;
case R.id.button1:
txt.append("1");
formulaContinuousClick = 0;
break;
case R.id.button2:
txt.append("2");
formulaContinuousClick = 0;
break;
case R.id.button3:
txt.append("3");
formulaContinuousClick = 0;
break;
case R.id.button4:
txt.append("4");
formulaContinuousClick = 0;
break;
case R.id.button5:
txt.append("5");
formulaContinuousClick = 0;
break;
case R.id.button6:
txt.append("6");
formulaContinuousClick = 0;
break;
case R.id.button7:
txt.append("7");
formulaContinuousClick = 0;
break;
case R.id.button8:
txt.append("8");
formulaContinuousClick = 0;
break;
case R.id.button9:
txt.append("9");
formulaContinuousClick = 0;
break;
case R.id.buttonBS:
formulaContinuousClick = 0;
//Get Editable instance
Editable editable = Editable.Factory.getInstance().newEditable(txt.getText());
//Processing to delete the last character each time the button is pressed
if(editable.length() > 0){
//The first argument of delete is start of the character you want to delete,The second argument is the end of the character you want to delete
editable.delete(editable.length()-1, editable.length());
}
//Set in TextView
txt.setText(editable, TextView.BufferType.EDITABLE);
break;
case R.id.buttonClear:
decimalPointCount = 0;
ClickedFormulaOnce = 0;
formulaContinuousClick = 0;
stringList.clear();
//For clearing the image
@SuppressLint("ResourceType")
ImageView iv = this.findViewById(R.id.imageView);
iv.setImageDrawable(null);
txt.setText(null);
break;
case R.id.buttonPoint:
//Judgment that prevents repeated decimal points.
if (decimalPointCount == 0) {
txt.append(".");
decimalPointCount = 1;
}
break;
//From here+-/*What happens when you click.
//formulaContinuousClick+-*/=For preventing continuous clicks.
//Clicked Formula Once+-*/For determining whether you clicked even once.
case R.id.buttonPlus:
formulaContinuousClick++;
// +-/*Processing when you press. Ignore for continuous taps.
//Also, if there is nothing in TextView, it will be ignored.
if(formulaContinuousClick == 1 && !(txt.getText().toString().equals(""))) {
ClickedFormulaOnce = 1;
txt.append("+");
}
decimalPointCount = 0; //Returns the decimal point click count to 0.
break;
case R.id.buttonMinus:
formulaContinuousClick++;
if(formulaContinuousClick == 1 && !(txt.getText().toString().equals(""))) {
ClickedFormulaOnce = 1;
txt.append("-");
}
decimalPointCount = 0;
break;
case R.id.buttonMulti:
formulaContinuousClick++;
ClickedFormulaOnce = 1;
if(formulaContinuousClick == 1 && !(txt.getText().toString().equals(""))) {
ClickedFormulaOnce = 1;
txt.append("×");
}
decimalPointCount = 0;
break;
case R.id.buttonDiv:
formulaContinuousClick++;
ClickedFormulaOnce = 1;
if(formulaContinuousClick == 1 && !(txt.getText().toString().equals(""))) {
ClickedFormulaOnce = 1;
txt.append("÷");
}
decimalPointCount = 0;
break;
case R.id.buttonEqual:
if(ClickedFormulaOnce == 1) {
formulaContinuousClick++;
}
if (ClickedFormulaOnce == 1 && formulaContinuousClick == 1) {
formulaContinuousClick = 0;
ClickedFormulaOnce = 0;
//Prevents additional decimal points when the calculation result has a decimal point. Example "3.3+0.1=3.4 → Click the decimal point → "3".4."Such
decimalPointCount = 1;
if(txt.getText().toString().length() > 56) {
Context context = getApplicationContext();
Toast.makeText(context, "The number of characters exceeds the upper limit of 56 characters.", Toast.LENGTH_LONG).show();
} else {
calculation(txt);
}
}
break;
}
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:shrinkColumns="0,1,2,3,4">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="2"
android:orientation="vertical">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:textSize="50sp" />
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" />
</LinearLayout>
<TableRow
android:id="@+id/row1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="2">
<Button
android:id="@+id/button7"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:onClick="btnCurrent_onClick"
android:text="@string/button7"
android:textSize="25sp" />
<Button
android:id="@+id/button8"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:onClick="btnCurrent_onClick"
android:text="@string/button8"
android:textSize="25sp" />
<Button
android:id="@+id/button9"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:onClick="btnCurrent_onClick"
android:text="@string/button9"
android:textSize="25sp" />
<Button
android:id="@+id/buttonDiv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:background="#FFBF00"
android:onClick="btnCurrent_onClick"
android:text="@string/buttonDiv"
android:textSize="25sp" />
<Button
android:id="@+id/buttonClear"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:background="#FF4000"
android:onClick="btnCurrent_onClick"
android:text="@string/buttonClear"
android:textSize="25sp" />
</TableRow>
<TableRow
android:id="@+id/row2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="2">
<Button
android:id="@+id/button4"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:onClick="btnCurrent_onClick"
android:text="@string/button4"
android:textSize="25sp" />
<Button
android:id="@+id/button5"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:onClick="btnCurrent_onClick"
android:text="@string/button5"
android:textSize="25sp" />
<Button
android:id="@+id/button6"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:onClick="btnCurrent_onClick"
android:text="@string/button6"
android:textSize="25sp" />
<Button
android:id="@+id/buttonMulti"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:background="#FFBF00"
android:onClick="btnCurrent_onClick"
android:text="@string/buttonMulti"
android:textSize="25sp" />
<Button
android:id="@+id/buttonBS"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:background="#00ffff"
android:onClick="btnCurrent_onClick"
android:text="@string/buttonBS"
android:textSize="25sp" />
</TableRow>
<TableRow
android:id="@+id/row3"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="2">
<Button
android:id="@+id/button1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:onClick="btnCurrent_onClick"
android:text="@string/button1"
android:textSize="25sp" />
<Button
android:id="@+id/button2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:onClick="btnCurrent_onClick"
android:text="@string/button2"
android:textSize="25sp" />
<Button
android:id="@+id/button3"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:onClick="btnCurrent_onClick"
android:text="@string/button3"
android:textSize="25sp" />
<Button
android:id="@+id/buttonPlus"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:background="#FFBF00"
android:onClick="btnCurrent_onClick"
android:text="@string/buttonPlus"
android:textSize="25sp" />
<Button
android:id="@+id/buttonMinus"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:background="#FFBF00"
android:onClick="btnCurrent_onClick"
android:text="@string/buttonMinus"
android:textSize="40sp" />
</TableRow>
<TableRow
android:id="@+id/row4"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1">
<Button
android:id="@+id/button0"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_span="2"
android:onClick="btnCurrent_onClick"
android:text="@string/button0"
android:textSize="25sp" />
<Button
android:id="@+id/buttonPoint"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:onClick="btnCurrent_onClick"
android:text="@string/buttonPoint"
android:textSize="40sp" />
<Button
android:id="@+id/buttonEqual"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:layout_span="2"
android:background="#2EFE64"
android:onClick="btnCurrent_onClick"
android:text="@string/buttonEqual"
android:textSize="25sp" />
</TableRow>
string.xml
<resources>
<string name="app_name">Caluculator</string>
<string name="button0">0</string>
<string name="button1">1</string>
<string name="button2">2</string>
<string name="button3">3</string>
<string name="button4">4</string>
<string name="button5">5</string>
<string name="button6">6</string>
<string name="button7">7</string>
<string name="button8">8</string>
<string name="button9">9</string>
<string name="buttonPlus">+</string>
<string name="buttonMinus">-</string>
<string name="buttonMulti">×</string>
<string name="buttonDiv">÷</string>
<string name="buttonPoint">.</string>
<string name="buttonEqual">=</string>
<string name="buttonClear">C</string>
<string name="buttonBS">BS</string>
</resources>
Recommended Posts