** 사칙연산(괄호 가능) **
0. 프로젝트명 : KeyPadAll
1. 사칙연산을 Queue에 넣다 빼면서 처리
2. 괄호 가능
3. 화면 :
5. 안드로이드 버전
- 스튜디오 : v2.2.3
- Minumum SDK : API 19:Android 4.4. (KitKat)
6. 소스목록
1. MainActivity.java
2. Calculator.java
3. activity_main.xml
4. drawable/border_calbutton.xml
5. drawable/border_layout.xml
6. values/colors.xml
6. 소스
|
1. MainActivity.java |
|
package com.example.farmer.keypadall;
import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
EditText arithmetic; TextView result;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);
arithmetic = (EditText)findViewById(R.id.et_arithmetic); result = (TextView)findViewById(R.id.tv_result);
((TextView)findViewById(R.id.tv_mqrquee)).setSelected(true);
//arithmetic.requestFocus(); //포커스 주기 arithmetic.setFocusableInTouchMode(false); // 결과 box에 edit막기 : ok arithmetic.setKeyListener(null); //key 가 안눌림. 하지만 keypad가 보임 }
//--------------------------------------------------------------------------- // 사칙연산자 클릭 시 // - 사칙연산자가 중복 시 최종연산자로 대체 //--------------------------------------------------------------------------- public void arithmeticOrganOnClick(View view){ String sCurrNum = arithmetic.getText().toString();
if (sCurrNum.length() == 0) return;
String lastChar = sCurrNum.substring(sCurrNum.length()-1, sCurrNum.length()); if ("+-*/".indexOf(lastChar) >= 0){ arithmetic.setText( sCurrNum.substring(0, sCurrNum.length()-1) + ((Button)view).getText()); }else{ arithmetic.setText( sCurrNum + ((Button)view).getText()); } }
//--------------------------------------------------------------------------- // 숫자 클릭 시 //--------------------------------------------------------------------------- public void numberOnClick(View view){ arithmetic.setText( arithmetic.getText().toString() + ((Button)view).getText()); } //--------------------------------------------------------------------------- // 소수점 클릭 시 //--------------------------------------------------------------------------- public void pointOnClick(View view){ arithmetic.setText( arithmetic.getText().toString() + ((Button)view).getText()); }
//--------------------------------------------------------------------------- // BackClear 버튼 클릭 시 //--------------------------------------------------------------------------- public void oneCharClearOnClick(View view){ String sCurrNum = arithmetic.getText().toString(); //? getText() : Return이 Editable ?
//Log.d("farm-1", sNum1); //?log가 안보임 ? if (sCurrNum.length() > 0) { //Log.d("farm-2", sNum1); sCurrNum = sCurrNum.substring(0, sCurrNum.length() - 1); //Log.d("farm-3", sNum1); arithmetic.setText(sCurrNum);
//포커스를 맨 뒤로 하기 //Editable editable = arithmetic.getText(); //Selection.setSelection(editable, editable.length()); } }
//--------------------------------------------------------------------------- // Clear 버튼 클릭 시 //--------------------------------------------------------------------------- public void allClearOnClick(View view){ arithmetic.setText(""); result.setText(""); }
//--------------------------------------------------------------------------- // ()괄호 버튼 클릭 시 // 1. 숫자 다음에 ( 여는 괄호는 올 수 없음 // 2. 사칙연산자 다음이 ) 닫는 괄호는 올 수 없음 //--------------------------------------------------------------------------- public void bracketOnclick(View view){ String sCurrNum = arithmetic.getText().toString();
switch (view.getId()){ case R.id.bt_braketLeft: if (sCurrNum.length() > 0) { String lastChar = sCurrNum.substring(sCurrNum.length()-1, sCurrNum.length()); Toast.makeText(MainActivity.this, "lastChar=" + lastChar, Toast.LENGTH_SHORT).show(); if ("0123456789".indexOf(lastChar) >= 0) return; } break; case R.id.bt_braketRight: if (sCurrNum.length() > 0) { String lastChar = sCurrNum.substring(sCurrNum.length()-1, sCurrNum.length()); if ("+0*/".indexOf(lastChar) >= 0) return; } break; }
arithmetic.setText( arithmetic.getText().toString() + ((Button)view).getText()); }
//--------------------------------------------------------------------------- // 계산 버튼 클릭 시 //--------------------------------------------------------------------------- public void calculatorOnClick(View view) throws Exception{ Calculator calculator = new Calculator();
String sCurrNum = arithmetic.getText().toString(); String resultVal = calculator.bracketCalMain(sCurrNum); result.setText(resultVal); } } |
|
2. Calculator.java |
|
package com.example.farmer.keypadall;
import java.util.LinkedList; import java.util.Queue; import java.math.BigDecimal;
/** * Created by kyh on 2017-01-02. */
public class Calculator { //------------------------------------------------------------------------ // 괄호 까지 존재하는 사칙연사 //------------------------------------------------------------------------ @SuppressWarnings({ "rawtypes", "unchecked" }) public static String bracketCalMain(String sNumList) throws Exception{ //0. ( ) 괄호 갯수 검증 if (checkBracket(sNumList) == false) return "괄호 () 갯수가 Match되지 않습니다.";
// 1. 1차 문자열 Parsing Queue firstQueue = new LinkedList(); firstQueue = stringParsing(sNumList); System.out.println("----------------------------------------------"); System.out.println("괄호 1차 => " + firstQueue.toString());
// 2. 2차 괄호안 계산 Queue secondQueue = new LinkedList(); String oneChar; while(firstQueue.peek() != null){ oneChar = firstQueue.poll().toString(); //System.out.println("괄호 => " + oneChar);
if ("()".indexOf(oneChar) >= 0){ //괄호안 계산 (firstQueue) secondQueue.offer(braketInCal(firstQueue)); }else{ secondQueue.offer(oneChar); } }
//3. Queue에 저장 된 값 중 곱셈. 나눗셈 계산 secondQueue = multiplyDivideCal(secondQueue);
//4. Queue에 저장 된 값 중 덧셈. 뺄샘 계산 String sResult = addSubtractCal(secondQueue); System.out.println("괄호 최종결과 => " + sResult); return sResult; }
//( ) 괄호 갯수 검증 public static boolean checkBracket(String sNumList){ int count1=0, count2=0; for(int i=0; i<sNumList.length(); i++){ if ("(".equals(sNumList.substring(i, i+1))){ count1 ++; }else if (")".equals(sNumList.substring(i, i+1))){ count2 ++; } }
if (count1 == count2) return true; else{ System.out.println("괄호 () 갯수가 Match되지 않습니다."); return false; } }
//------------------------------------------------------------------------ // 1차. 문자열 Parsing //------------------------------------------------------------------------ @SuppressWarnings({ "rawtypes", "unchecked" }) public static Queue stringParsing(String sNumList){ String sOneNum = ""; //하나의 숫자열 Queue firstQueue = new LinkedList(); for(int i=0; i<sNumList.length(); i++){ String oneChar = sNumList.substring(i, i+1); if ("+-*/()".indexOf(oneChar) >= 0 ){
// 3+(3 과 같이 4칙연산자와 괄호가 동시에 존재 하는 경우 때문 if (!"".equals(sOneNum)) firstQueue.offer(sOneNum); firstQueue.offer(oneChar); sOneNum = ""; }else{ sOneNum += oneChar;
if (i+1 == sNumList.length()){ firstQueue.offer(sOneNum); } } } return firstQueue; }
//------------------------------------------------------------------------ // 2차. 괄호 내부 계산 (재귀적 호출) //------------------------------------------------------------------------ @SuppressWarnings({ "unchecked", "rawtypes" }) public static String braketInCal(Queue firstQueue) throws Exception{ String oneChar; //1. 괄호 내부에 존재 하는 값을 Queue에 저장 Queue secondQueue = new LinkedList(); while(firstQueue.peek() != null){ oneChar = firstQueue.poll().toString(); if ("(".equals(oneChar)){ //괄호안 계산 (firstQueue) secondQueue.offer(braketInCal(firstQueue)); }else if (")".equals(oneChar)){ break; //닫기 괄호가 나오면 stop }else{ secondQueue.offer(oneChar); } } System.out.println("괄호 2차 => " + secondQueue.toString());
//2. Queue에 저장 된 값 중 곱셈. 나눗셈 계산 secondQueue = multiplyDivideCal(secondQueue);
//3. Queue에 저장 된 값 중 덧셈. 뺄샘 계산 String sResult = addSubtractCal(secondQueue);
return sResult; }
//------------------------------------------------------------------------ // 곱셈, 나눗셈 계산 //------------------------------------------------------------------------ @SuppressWarnings({ "rawtypes", "unchecked" }) public static Queue multiplyDivideCal(Queue inQueue) throws Exception{ Queue outQueue = new LinkedList(); String oneChar; String sNum1 = "", sNum2 = "", sResult = ""; String operator = ""; BigDecimal nResult = new BigDecimal("0"); while(inQueue.peek() != null){ oneChar = inQueue.poll().toString();
if ("+-".indexOf(oneChar) >= 0 ){ outQueue.offer(sNum1); outQueue.offer(oneChar); sNum1 = ""; }else if ("*/".indexOf(oneChar) >= 0 ) { operator = oneChar; }else{ if ("".equals(sNum1)){ sNum1 = oneChar; }else if ("".equals(sNum2)) { sNum2 = oneChar; if ("*".equals(operator)) { nResult = (new BigDecimal(sNum1)).multiply(new BigDecimal(sNum2)); }else if ("/".equals(operator)) { if ("0".equals(sNum2)){ throw new Exception("나눗셈 분모에 0 이 존재 합니다."); }
nResult = (new BigDecimal(sNum1)).divide(new BigDecimal(sNum2), 6, BigDecimal.ROUND_UP); } sResult = String.valueOf(nResult);
sNum1 = sResult; sNum2 = ""; operator = ""; } }
if (inQueue.peek() == null) outQueue.offer(sNum1); } return outQueue; }
//------------------------------------------------------------------------ // 덧셈. 뺄샘 계산 //------------------------------------------------------------------------ @SuppressWarnings({ "rawtypes" }) public static String addSubtractCal(Queue inQueue){ String operator = ""; String oneChar = ""; BigDecimal nResult = new BigDecimal(inQueue.poll().toString()); while(inQueue.peek() != null){ oneChar = inQueue.poll().toString();
if ("+-".indexOf(oneChar) >= 0 ){ operator = oneChar; }else{ if ("+".equals(operator)){ nResult = nResult.add(new BigDecimal(oneChar)); }else if ("-".equals(operator)){ nResult = nResult.subtract(new BigDecimal(oneChar)); } operator = ""; } } return nResult.toString(); } }
|
|
3. activity_main.xml |
|
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_keypad" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#d1cdcd" android:orientation="vertical" tools:context="com.example.farmer.keypadall.MainActivity">
<!-- 0차 : mqrquee --> <RelativeLayout android:layout_width="match_parent" android:layout_height="0dp" android:background="#00ffffff" android:layout_weight="1">
<TextView android:id="@+id/tv_mqrquee" android:textSize="30dp" android:padding="10dp" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_centerInParent="true" android:text="농부의 4칙연산 계산기. 자체개발 완료.. 으미 힘든거~~~~~~" android:ellipsize="marquee" android:focusable="true" android:marqueeRepeatLimit="marquee_forever" android:singleLine="true"/> </RelativeLayout> <!-- 1차 : 산술식 --> <RelativeLayout android:layout_width="match_parent" android:layout_height="0dp" android:background="#b4b2b7" android:layout_weight="1">
<TextView android:id="@+id/tv_num" android:padding="10dp" android:layout_width="90dp" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_centerInParent="true" android:text="4칙 연산식"/>
<EditText android:id="@+id/et_arithmetic" android:layout_marginRight="10dp" android:layout_width="match_parent" android:layout_height="30dp" android:hint="4칙 연산식을 입력 하시오." android:paddingLeft="10dp" android:background="#ffffff" android:layout_centerInParent="true" android:layout_toRightOf="@+id/tv_num" />
</RelativeLayout>
<!-- 2차 : 결과 --> <RelativeLayout android:layout_width="match_parent" android:layout_height="0dp" android:background="#d7c6ed" android:layout_weight="1">
<TextView android:id="@+id/tv_resultLabel" android:padding="10dp" android:layout_width="90dp" android:layout_height="wrap_content" android:layout_centerInParent="true" android:layout_alignParentLeft="true" android:text="Result"/>
<TextView android:id="@+id/tv_result" android:textSize="20dp" android:layout_marginRight="10dp" android:layout_width="match_parent" android:layout_height="30dp" android:text="" android:paddingLeft="10dp" android:background="#e4e4dd" android:layout_centerInParent="true" android:layout_toRightOf="@+id/tv_resultLabel"/>
</RelativeLayout>
<!-- 3차 : 빈 공백 --> <RelativeLayout android:layout_width="match_parent" android:layout_height="0dp" android:background="#fcfcfc" android:layout_weight="0.2"> </RelativeLayout>
<!-- 4차 : 기타 C, ( ) / "#6a00ff" --> <RelativeLayout android:layout_width="match_parent" android:layout_height="0dp" android:background="@drawable/border_layout" android:layout_weight="1">
<Button android:id="@+id/bt_clear" android:onClick="allClearOnClick" android:text="C" android:textSize="30dp" android:layout_width="75dp" android:layout_height="45dp" android:layout_marginLeft="30dp" android:layout_alignParentLeft="true" android:layout_centerVertical="true" android:background="@drawable/border_calbutton"/> <Button android:id="@+id/bt_braketLeft" android:onClick="bracketOnclick" android:text="(" android:textSize="30dp" android:layout_width="75dp" android:layout_height="45dp" android:layout_toRightOf="@+id/bt_clear" android:layout_centerVertical="true" android:background="@drawable/border_calbutton"/> <Button android:id="@+id/bt_braketRight" android:onClick="bracketOnclick" android:text=")" android:textSize="30dp" android:layout_width="75dp" android:layout_height="45dp" android:layout_toRightOf="@+id/bt_braketLeft" android:layout_centerVertical="true" android:background="@drawable/border_calbutton"/> <Button android:id="@+id/bt_divide" android:onClick="arithmeticOrganOnClick" android:text="/" android:textSize="30dp" android:layout_width="75dp" android:layout_height="45dp" android:layout_toRightOf="@+id/bt_braketRight" android:layout_centerVertical="true" android:background="@drawable/border_calbutton"/>
</RelativeLayout>
<!-- 5차 : 7,8,9, * --> <RelativeLayout android:layout_width="match_parent" android:layout_height="0dp" android:background="@drawable/border_layout" android:layout_weight="1">
<Button android:id="@+id/bt_seven" android:onClick="numberOnClick" android:text="7" android:textSize="30dp" android:layout_width="75dp" android:layout_height="match_parent" android:layout_marginLeft="30dp" android:layout_alignParentLeft="true" android:layout_centerVertical="true" /> <Button android:id="@+id/bt_eight" android:onClick="numberOnClick" android:text="8" android:textSize="30dp" android:layout_width="75dp" android:layout_height="match_parent" android:layout_toRightOf="@+id/bt_seven" android:layout_centerVertical="true" /> <Button android:id="@+id/bt_nine" android:onClick="numberOnClick" android:text="9" android:textSize="30dp" android:layout_width="75dp" android:layout_height="match_parent" android:layout_toRightOf="@+id/bt_eight" android:layout_centerVertical="true" /> <Button android:id="@+id/bt_multiply" android:onClick="arithmeticOrganOnClick" android:text="*" android:textSize="30dp" android:layout_width="75dp" android:layout_height="45dp" android:layout_toRightOf="@+id/bt_nine" android:layout_centerVertical="true" android:background="@drawable/border_calbutton"/>
</RelativeLayout>
<!-- 6차 : 4,5,6,- --> <RelativeLayout android:layout_width="match_parent" android:layout_height="0dp" android:background="@drawable/border_layout" android:layout_weight="1">
<Button android:id="@+id/bt_four" android:onClick="numberOnClick" android:text="4" android:textSize="30dp" android:layout_width="75dp" android:layout_height="match_parent" android:layout_marginLeft="30dp" android:layout_alignParentLeft="true" android:layout_centerVertical="true" /> <Button android:id="@+id/bt_five" android:onClick="numberOnClick" android:text="5" android:textSize="30dp" android:layout_width="75dp" android:layout_height="match_parent" android:layout_toRightOf="@+id/bt_four" android:layout_centerVertical="true" /> <Button android:id="@+id/bt_six" android:onClick="numberOnClick" android:text="6" android:textSize="30dp" android:layout_width="75dp" android:layout_height="match_parent" android:layout_toRightOf="@+id/bt_five" android:layout_centerVertical="true" /> <Button android:id="@+id/bt_minus" android:onClick="arithmeticOrganOnClick" android:text="-" android:textSize="30dp" android:layout_width="75dp" android:layout_height="45dp" android:layout_toRightOf="@+id/bt_six" android:layout_centerVertical="true" android:background="@drawable/border_calbutton"/>
</RelativeLayout>
<!-- 7차 : 1,2,3,+ --> <RelativeLayout android:layout_width="match_parent" android:layout_height="0dp" android:background="@drawable/border_layout" android:layout_weight="1">
<Button android:id="@+id/bt_one" android:onClick="numberOnClick" android:text="1" android:textSize="30dp" android:layout_width="75dp" android:layout_height="match_parent" android:layout_marginLeft="30dp" android:layout_alignParentLeft="true" android:layout_centerVertical="true" /> <Button android:id="@+id/bt_two" android:onClick="numberOnClick" android:text="2" android:textSize="30dp" android:layout_width="75dp" android:layout_height="match_parent" android:layout_toRightOf="@+id/bt_one" android:layout_centerVertical="true" /> <Button android:id="@+id/bt_three" android:onClick="numberOnClick" android:text="3" android:textSize="30dp" android:layout_width="75dp" android:layout_height="match_parent" android:layout_toRightOf="@+id/bt_two" android:layout_centerVertical="true" /> <Button android:id="@+id/bt_plus" android:onClick="arithmeticOrganOnClick" android:text="+" android:textSize="30dp" android:layout_width="75dp" android:layout_height="45dp" android:layout_toRightOf="@+id/bt_three" android:layout_centerVertical="true" android:background="@drawable/border_calbutton"/>
</RelativeLayout>
<!-- 8차 : 0, . <- = --> <RelativeLayout android:layout_width="match_parent" android:layout_height="0dp" android:background="@drawable/border_layout" android:layout_weight="1">
<Button android:id="@+id/bt_zero" android:onClick="numberOnClick" android:text="0" android:textSize="30dp" android:layout_width="75dp" android:layout_height="match_parent" android:layout_marginLeft="30dp" android:layout_alignParentLeft="true" android:layout_centerVertical="true" /> <Button android:id="@+id/bt_point" android:onClick="pointOnClick" android:text="." android:textSize="30dp" android:layout_width="75dp" android:layout_height="45dp" android:layout_toRightOf="@+id/bt_zero" android:layout_centerVertical="true" android:background="@drawable/border_calbutton"/> <Button android:id="@+id/bt_back" android:onClick="oneCharClearOnClick" android:text="←" android:textSize="30dp" android:layout_width="75dp" android:layout_height="45dp" android:layout_toRightOf="@+id/bt_point" android:layout_centerVertical="true" android:background="@drawable/border_calbutton"/> <Button android:id="@+id/bt_calculator" android:onClick="calculatorOnClick" android:text="=" android:textSize="30dp" android:layout_width="75dp" android:layout_height="45dp" android:layout_toRightOf="@+id/bt_back" android:layout_centerVertical="true" android:background="@drawable/border_calbutton"/>
</RelativeLayout>
<!-- 9차 : 빈공백 --> <RelativeLayout android:layout_width="match_parent" android:layout_height="0dp" android:background="#00ffffff" android:layout_weight="0.5"> </RelativeLayout> </LinearLayout> |
|
4. drawable/border_calbutton.xml |
|
<?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 설정된 위젯의 background를 설정 1. 아래 body설정 부분에서 전체영역이 설정 되면 이 background는 아무 표시가 안난다. 2. 아래 body설정 부분에서 top,bottom,left,right에 2dp씩 설정 되었기에 이 2dp만큼 아래 부분에 설정된 모양(rectangle)과 색깔(#f9c7cc)이 보인다. --> <item> <shape android:shape="rectangle"> <solid android:color="#f9c7cc" /> </shape> </item>
<!-- 설정된 위젯의 Body를 설정 1. top,bottom,left,right 에 2dp 설정 2. shape : body를 사각형으로 설정 3. color : body에 color지정 --> <item android:top="2dp" android:bottom="2dp" android:left="2dp" android:right="2dp"> <shape android:shape="rectangle"> <solid android:color="#d4d2d2" /> </shape> </item> </layer-list>
|
|
5. drawable/border_layout.xml |
|
<?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 설정된 위젯의 background를 설정 1. 아래 body설정 부분에서 전체영역이 설정 되면 이 background는 아무 표시가 안난다. 2. 아래 body설정 부분에서 top, bottom에 2dp씩 설정 되었기에 이 2dp만큼 아래 부분에 설정된 모양(oval)과 색깔(#6a00ff)이 보인다. --> <item> <shape android:shape="oval"> <solid android:color="#6a00ff" /> </shape> </item>
<!-- 설정된 위젯의 Body를 설정 1. top, bottom 에 2dp 설정 2. shape : body를 사각형으로 설정 3. color : body에 color지정 --> <item android:top="2dp" android:bottom="2dp"> <shape android:shape="rectangle"> <solid android:color="#eeffffff" /> </shape> </item> </layer-list>
|
|
6. values/colors.xml |
|
<?xml version="1.0" encoding="utf-8"?> <resources> <color name="colorPrimary">#3F51B5</color> <color name="colorPrimaryDark">#303F9F</color> <color name="colorAccent">#FF4081</color> <drawable name="bg_select">#2196F3</drawable> <drawable name="bg">#EEEEEE</drawable> </resources> |