ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • pt.1~3)안드로이드 스튜디오 계산기 (프로젝트 생성부터 완성까지!)
    Java/Android Studio 2020. 9. 10. 18:00

    Android Studio 를 이용해 계산기를 만들어보자!

     

     

    1. 프로젝트 생성하기

     

     

    [File]-[New]-[New Project]

    새로운 프로젝트를 생성한다.

     

    Empty Activity

    이번시간에는 텅 빈 액티비티를 선택한다.

     

    Next를 누르면 프로젝트 이름과 경로를 설정하는 창이 나온다. 설정이 완료되면 [Finish]

     

    activity_main.xml

    실행하면 가장 기본적인 요소 2가지가 보인다.

     

    activity_main.xml은 인터페이스를 구성하는 요소이고 MainActivity는 함수를 컨트롤하는 부분이다.

     

    activity_main.xml 과 MainActivity.java

    ASP.NET으로 비유하면  activity_main.xml 과 MainActivity.java는 각각 뷰와 컨트롤에 대응한다.

     

    2. 에뮬레이터 실행하기

     

    AVD Manager를 실행시킨다.

     

    필자는 이미 에뮬레이터를 생성해서 Galaxy S7 API R이 보인다.

     

    +Create Virtual Device를 눌러 가상머신을 생성하자

     

     

    가상머신의 기종을 선택하자. 원하는 기종이 없을 경우 스펙을 직접 입력하거나 import할 수 있다.

     

    시스템 이미지 설정

     

    여기서 이미지란 일반적으로 뜻하는 사진이 아닌 OS를 구동하기 위한 패키지를 뜻한다.

     

    기타 설정을 마치고 [Finish]

     

    상단의 Run app 버튼을 누른다 (Shift + F10)

     

    에뮬레이터가 실행되고 현재까지 만들어진 어플리케이션이 실행된다.

     

    스마트폰 연결 없이도 테스트 실행을 해볼 수 있는 것이다.

     

    또는 안드로이드 스마트폰을 연결해서 앱을 직접 실행할 수 있다.

     

    그러기 위해서는 개발자 모드를 실행하고 USB연결을 해줘야 한다. 

     

    다음 글에 개발자 모드 설정법이 잘 나와있다. 

     

    nature2public.tistory.com/39

     

    갤럭시 S7 개발자 모드 알아보기 (Galaxy S7 Developer Mode Options)

    갤럭시 S7 개발자 모드 알아보기 (Galaxy S7 Developer Mode Options) 이번 포스팅은 개발자 옵션을 적용하여 보고 어떠한 기능을 추가하고 적용할 수 있는지 그리고 개발자 모드로 접근하는 방법에 대하��

    nature2public.tistory.com

     

    요약하자면 [설정]-[디바이스 정보] - [소프트웨어 정보] - [빌드 번호] 를 여러번 클릭해준다.

     

    그러면 

     

    위와 같이 맨 밑에 개발자 옵션이 생긴다. 

     

    들어가서 USB 디버깅을 ON 해주는 것도 잊지 말자.

     

    이까지 하면 기본적인 개발 준비가 완료되었다.

     

     

    계산기 프로그램 출처: dirrito.tistory.com/13

     

     

    3. 컨트롤 추가하기

     

    먼저 컨트롤을 추가해 보자

     

     

    다시 activity_main.xml을 가보면 우측 상단에 3개의 아이콘이 보인다.

     

    각각 코드-분할-디자인 으로 [코드]만 보거나 [코드랑 디자인] 둘다 보거나 [디자인]만 볼 수 있다.

     

    위 사진은 디자인이다.

     

     

     

    디자인에서는 컨트롤을 드래그 앤 드롭으로 쉽게 추가할 수 있어서 가시성이 좋다.

     

    Palette의 컨트롤들을 화면 또는 Component tree에 드롭할 수 있다.

     

    드래그 앱 드롭으로 LinearLayout(vertical)을 추가해 보았다.

     

    위와 같이 Component Tree에 추가됨을 알 수 있다.

     

    Component Tree에서 부모개체와 자식개체를 잘 정리해야 컨트롤이 꼬이는 걸 방지할 수 있다.

     

     

    activity_main.xml 파일에 바로 반영됨을 알 수 있다.

     

    xml 파일에 위 같은 형식으로 입력해도 컨트롤은 똑같이 추가된다.

     

    레이아웃 설정없이 마구잡이로 컨트롤을 추가하면 어플 실행시 좌상단에 컨트롤들이 몰려있는 현상이 생길 수 있다.

     

     

    다음과 같이 xml 파일을 작성해본다.

     

    [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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">
    
    <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_weight="1.5"
    android:orientation="vertical">
    
    <ScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_weight="1">
    
    <TextView
    android:id="@+id/first_textView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="10dp"
    android:text=""
    android:textSize="30dp" />
    </ScrollView>
    
    <TextView
    android:id="@+id/second_textView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="10dp"
    android:layout_weight="2"
    android:text=""
    android:textSize="30dp" />
    
    </LinearLayout>
    
    <GridLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_weight="1"
    android:columnCount="4"
    android:orientation="horizontal"
    android:rowCount="5">
    
    <Button
    android:id="@+id/clear"
    android:layout_rowWeight="1"
    android:layout_columnWeight="1"
    android:layout_margin="-5dp"
    android:text="C" />
    
    <Button
    android:id="@+id/bracket"
    android:layout_rowWeight="1"
    android:layout_columnWeight="1"
    android:layout_margin="-5dp"
    android:text="( )" />
    
    <Button
    android:id="@+id/percent"
    android:layout_rowWeight="1"
    android:layout_columnWeight="1"
    android:layout_margin="-5dp"
    android:text="%" />
    
    <Button
    android:id="@+id/div"
    android:layout_rowWeight="1"
    android:layout_columnWeight="1"
    android:layout_margin="-5dp"
    android:text="÷" />
    
    
    <Button
    android:id="@+id/num7"
    android:layout_rowWeight="1"
    android:layout_columnWeight="1"
    android:layout_margin="-5dp"
    android:text="7" />
    
    <Button
    android:id="@+id/num8"
    android:layout_rowWeight="1"
    android:layout_columnWeight="1"
    android:layout_margin="-5dp"
    android:text="8" />
    
    <Button
    android:id="@+id/num9"
    android:layout_rowWeight="1"
    android:layout_columnWeight="1"
    android:layout_margin="-5dp"
    android:text="9" />
    
    <Button
    android:id="@+id/mul"
    android:layout_rowWeight="1"
    android:layout_columnWeight="1"
    android:layout_margin="-5dp"
    android:text="X" />
    
    
    <Button
    android:id="@+id/num4"
    android:layout_rowWeight="1"
    android:layout_columnWeight="1"
    android:layout_margin="-5dp"
    android:text="4" />
    
    <Button
    android:id="@+id/num5"
    android:layout_rowWeight="1"
    android:layout_columnWeight="1"
    android:layout_margin="-5dp"
    android:text="5" />
    
    <Button
    android:id="@+id/num6"
    android:layout_rowWeight="1"
    android:layout_columnWeight="1"
    android:layout_margin="-5dp"
    android:text="6" />
    
    <Button
    android:id="@+id/sub"
    android:layout_rowWeight="1"
    android:layout_columnWeight="1"
    android:layout_margin="-5dp"
    android:text="-" />
    
    
    <Button
    android:id="@+id/num1"
    android:layout_rowWeight="1"
    android:layout_columnWeight="1"
    android:layout_margin="-5dp"
    android:text="1" />
    
    <Button
    android:id="@+id/num2"
    android:layout_rowWeight="1"
    android:layout_columnWeight="1"
    android:layout_margin="-5dp"
    android:text="2" />
    
    <Button
    android:id="@+id/num3"
    android:layout_rowWeight="1"
    android:layout_columnWeight="1"
    android:layout_margin="-5dp"
    android:text="3" />
    
    <Button
    android:id="@+id/add"
    android:layout_rowWeight="1"
    android:layout_columnWeight="1"
    android:layout_margin="-5dp"
    android:text="+" />
    
    
    <Button
    android:id="@+id/back"
    android:layout_rowWeight="1"
    android:layout_columnWeight="1"
    android:layout_margin="-5dp"
    android:text="back" />
    
    <Button
    android:id="@+id/num0"
    android:layout_rowWeight="1"
    android:layout_columnWeight="1"
    android:layout_margin="-5dp"
    android:text="0" />
    
    <Button
    android:id="@+id/dot"
    android:layout_rowWeight="1"
    android:layout_columnWeight="1"
    android:layout_margin="-5dp"
    android:text="." />
    
    <Button
    android:id="@+id/equal"
    android:layout_rowWeight="1"
    android:layout_columnWeight="1"
    android:layout_margin="-5dp"
    android:text="=" />
    
    </GridLayout>
    </LinearLayout>

     

    LinearLayoutLinearLayout─ScrollViewfirst_textView

                                      └second_textView

                    GridLayout(버튼20개)

     

    의 구조로 되어있다.

     

    버튼은 

    <Button
    android:id="@+id/equal"                           "equal"로 아이디 설정
    android:layout_rowWeight="1"
    android:layout_columnWeight="1"
    android:layout_margin="-5dp"
    android:text="=" />                                 "="로 텍스트 설정

    id와 텍스트를 설정해준다. 이외에 layout_rowWeight, layout_columnWeight 은 열, 행에서 버튼간의 비율을 설정할 때

     

    쓴다. margin은 여백을 나타낸다.

     

    xml을 수정하고 디자인을 확인하면

     

    위와같이 되어있다.

     

    버튼의 text를 설정한대로 보인다.

     

    다음은

     

    1. MainActivity.java를 수정한다.

    2. CalculateHelper 클래스를 추가한다.

     

     

     

     

    MainActivity.java.를 다음과 같이 수정한다.

     

    [MainActivity.java]

    package com.example.dumb;
    
    import androidx.appcompat.app.AppCompatActivity;
    
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;
    import android.widget.TextView;
    
    public class MainActivity extends AppCompatActivity {
    
    CalculateHelper calculateHelper;
    
    boolean isDot;
    boolean isBracket;
    boolean isPreview;
    
    TextView textView;
    TextView textView2;
    
    int size;
    String result;
    
    Button num0;
    Button num1;
    Button num2;
    Button num3;
    Button num4;
    Button num5;
    Button num6;
    Button num7;
    Button num8;
    Button num9;
    
    Button add;
    Button sub;
    Button mul;
    Button div;
    Button clear;
    Button bracket;
    Button percent;
    Button back;
    Button dot;
    Button equal;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    
    calculateHelper = new CalculateHelper();
    
    size=0;
    setButton();
    setTextView();
    
    }
    
    private void setButton(){
    num0 = findViewById(R.id.num0);
    num1 = findViewById(R.id.num1);
    num2 = findViewById(R.id.num2);
    num3 = findViewById(R.id.num3);
    num4 = findViewById(R.id.num4);
    num5 = findViewById(R.id.num5);
    num6 = findViewById(R.id.num6);
    num7 = findViewById(R.id.num7);
    num8 = findViewById(R.id.num8);
    num9 = findViewById(R.id.num9);
    
    add = findViewById(R.id.add);
    sub = findViewById(R.id.sub);
    mul = findViewById(R.id.mul);
    div = findViewById(R.id.div);
    clear = findViewById(R.id.clear);
    bracket = findViewById(R.id.bracket);
    percent = findViewById(R.id.percent);
    back = findViewById(R.id.back);
    dot = findViewById(R.id.dot);
    
    equal = findViewById(R.id.equal);
    
    num0.setOnClickListener(numClickListener);
    num1.setOnClickListener(numClickListener);
    num2.setOnClickListener(numClickListener);
    num3.setOnClickListener(numClickListener);
    num4.setOnClickListener(numClickListener);
    num5.setOnClickListener(numClickListener);
    num6.setOnClickListener(numClickListener);
    num7.setOnClickListener(numClickListener);
    num8.setOnClickListener(numClickListener);
    num9.setOnClickListener(numClickListener);
    
    add.setOnClickListener(markClickListener);
    sub.setOnClickListener(markClickListener);
    mul.setOnClickListener(markClickListener);
    div.setOnClickListener(markClickListener);
    clear.setOnClickListener(markClickListener);
    bracket.setOnClickListener(markClickListener);
    percent.setOnClickListener(markClickListener);
    back.setOnClickListener(markClickListener);
    dot.setOnClickListener(markClickListener);
    
    equal.setOnClickListener(markClickListener);
    }
    
    Button.OnClickListener numClickListener = new View.OnClickListener() {
    @Override
    public void onClick(View v) {
    switch(v.getId()){
    case R.id.num0:textView.append("0");break;
    case R.id.num1:textView.append("1");break;
    case R.id.num2:textView.append("2");break;
    case R.id.num3:textView.append("3");break;
    case R.id.num4:textView.append("4");break;
    case R.id.num5:textView.append("5");break;
    case R.id.num6:textView.append("6");break;
    case R.id.num7:textView.append("7");break;
    case R.id.num8:textView.append("8");break;
    case R.id.num9:textView.append("9");break;
    }
    preview();
    }
    };
    
    Button.OnClickListener markClickListener = new View.OnClickListener(){
    @Override
    public void onClick(View v){
    switch (v.getId()) {
    case R.id.add:
    textView.append(" + ");
    isPreview = true;
    break;
    case R.id.sub:
    textView.append(" - ");
    isPreview = true;
    break;
    case R.id.mul:
    textView.append(" * ");
    isPreview = true;
    break;
    case R.id.div:
    textView.append(" / ");
    isPreview = true;
    break;
    case R.id.percent:
    textView.append(" % ");
    isPreview = true;
    break;
    case R.id.clear:
    textView.setText("");
    textView2.setText("");
    
    calculateHelper = new CalculateHelper();
    
    isPreview = false;
    
    break;
    case R.id.bracket:
    if (!isBracket) {
    textView.append("( ");
    isBracket = true;
    } else {
    textView.append(" )");
    isBracket = false;
    }
    
    isPreview = true;
    
    break;
    case R.id.back:
    size = textView.getText().length();
    
    if (size != 0)
    textView.setText(textView.getText().toString().substring(0, size - 1));
    
    if (size > 1) {
    if (calculateHelper.checkNumber(textView.getText().toString().substring(size - 2)))
    preview();
    else {
    isPreview = false;
    textView2.setText("");
    }
    }
    
    break;
    case R.id.dot:
    textView.append(".");
    isDot = true;
    break;
    case R.id.equal:
    result = textView.getText().toString();
    double r = calculateHelper.process(result);
    
    if (!isDot)
    textView.setText(String.valueOf((int) r));
    else
    textView.setText(String.valueOf(r));
    
    textView2.setText("");
    isDot = false;
    isPreview = false;
    break;
    }
    }
    };
    
    private void preview(){
    if(isPreview){
    result = textView.getText().toString();
    double r = calculateHelper.process(result);
    
    if(!isDot){
    textView2.setText(String.valueOf((int)r));
    }else{
    textView2.setText(String.valueOf(r));
    }
    }
    }
    
    private void setTextView(){
    textView = findViewById(R.id.first_textView);
    textView2 = findViewById(R.id.second_textView);
    }
    }

     

    여기서는 메인클래스 내에 CalculateHelper, TextView, Button을 선언한다.

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    
    calculateHelper = new CalculateHelper();
    
    size=0;
    setButton();
    setTextView();
    
    }

    OnCreate 즉 실행되면 가장 먼저 위에 선언한 CalculateHelper, TextView, Button을 인스턴스화 한다.

    Button.OnClickListener numClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
                switch(v.getId()){
                    case R.id.num0:textView.append("0");break;
                    case R.id.num1:textView.append("1");break;
                    case R.id.num2:textView.append("2");break;
                    case R.id.num3:textView.append("3");break;
                    case R.id.num4:textView.append("4");break;
                    case R.id.num5:textView.append("5");break;
                    case R.id.num6:textView.append("6");break;
                    case R.id.num7:textView.append("7");break;
                    case R.id.num8:textView.append("8");break;
                    case R.id.num9:textView.append("9");break;
                    }
                preview();
            }
        };

     

    숫자 버튼에 OnClickListener를 연결해준다.

     

    View에서 id를 받아서 각 버튼에 맞는 숫자를 textView에 더하도록 하는 함수다.

     

    Button.OnClickListener markClickListener = new View.OnClickListener(){
    @Override
    public void onClick(View v){
    switch (v.getId()) {
    case R.id.add:
    textView.append(" + ");
    isPreview = true;
    break;
    case R.id.sub:
    textView.append(" - ");
    isPreview = true;
    break;
    case R.id.mul:
    textView.append(" * ");
    isPreview = true;
    break;
    case R.id.div:
    textView.append(" / ");
    isPreview = true;
    break;
    case R.id.percent:
    textView.append(" % ");
    isPreview = true;
    break;
    case R.id.clear:
    textView.setText("");
    textView2.setText("");
    
    calculateHelper = new CalculateHelper();
    
    isPreview = false;
    
    break;
    case R.id.bracket:
    if (!isBracket) {
    textView.append("( ");
    isBracket = true;
    } else {
    textView.append(" )");
    isBracket = false;
    }
    
    isPreview = true;
    
    break;
    case R.id.back:
    size = textView.getText().length();
    
    if (size != 0)
    textView.setText(textView.getText().toString().substring(0, size - 1));
    
    if (size > 1) {
    if (calculateHelper.checkNumber(textView.getText().toString().substring(size - 2)))
        preview();
        else {
            isPreview = false;
            textView2.setText("");
            }
        }
    
            break;
            case R.id.dot:
            textView.append(".");
            isDot = true;
            break;
            case R.id.equal:
            result = textView.getText().toString();
            double r = calculateHelper.process(result);
    
            if (!isDot)
            textView.setText(String.valueOf((int) r));
            else
            textView.setText(String.valueOf(r));
    
            textView2.setText("");
            isDot = false;
            isPreview = false;
            break;
            }
        }
    };

     

    기호버튼도 마찬가지로 각각 버튼에 맞게 +,-,*,/ 를 textView에 더해준다. 

     

    isPreview는 사칙연산이나 괄호를 눌렀을때 true 그 이외에는 false로 설정된다.

     

    이 isPreview 변수는

     

    textView의 값을 result에 복사하고 CalculatorHelper에서 후위 표기식의 계산을 수행하도록 한다.

     

    그리고 그 결과값을 textView2로 옮긴다.

     

    4. CalculateHelper 클래스 추가

     

     

     

    [File]-[New]-[Java Class]를 통해 클래스를 추가한다.

     

    내용은 다음과 같이 작성한다.

     

     

    [CalculateHelper.java]

    package com.example.dumb;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.Stack;
    
    public class CalculateHelper {
    public static double num1;
    public static double num2;
    public static double resultNumber;
    
    private ArrayList splitTokens(String equation){
    String[] constant = equation.split(" ");
    
    ArrayList constantList = new ArrayList();
    double number=0;
    
    boolean flag= false;
    for(String data:constant){
    if(data.equals(" ")){
    continue;
    }
    if(checkNumber(data)){
    number = number*10+Double.parseDouble(data);
    flag=true;
    }
    else{
    if(flag){
    constantList.add(number);
    number=0;
    }
    flag=false;
    constantList.add(data);
    }
    }
    
    if(flag){
    constantList.add(number);
    }
    
    return constantList;
    }
    
    private ArrayList infixToPostfix(ArrayList constant){
    ArrayList result= new ArrayList();
    HashMap level = new HashMap();
    Stack stack = new Stack();
    
    level.put("*",3);
    level.put("/",3);
    level.put("+",2);
    level.put("-",2);
    level.put("(",1);
    
    for(Object object : constant){
    if(object.equals(")")){
    stack.push(object);
    }else if(object.equals(")")){
    while(!stack.peek().equals("(")){
    Object val = stack.pop();
    if(!val.equals("(")){
    result.add(val);
    }
    }
    stack.pop();
    }else if(level.containsKey(object)){
    if(stack.isEmpty()){
    stack.push(object);
    }else{
    if(Double.parseDouble(level.get(stack.peek()).toString()) >= Double.parseDouble(level.get(object).toString())){
    result.add(stack.pop());
    stack.push(object);
    }else{
    stack.push(object);
    }
    }
    }else{
    result.add(object);
    }
    }
    while(!stack.isEmpty()){
    result.add(stack.pop());
    }
    return result;
    }
    
    private Double postFixEval(ArrayList expr){
    Stack numberStack = new Stack();
    for(Object o : expr){
    if(o instanceof Double){
    numberStack.push(o);
    }else if(o.equals("+")){
    num1=(Double)numberStack.pop();
    num2=(Double)numberStack.pop();
    numberStack.push(num2+num1);
    }else if(o.equals("-")){
    num1=(Double)numberStack.pop();
    num2=(Double)numberStack.pop();
    numberStack.push(num2-num1);
    }else if(o.equals("*")){
    num1=(Double)numberStack.pop();
    num2=(Double)numberStack.pop();
    numberStack.push(num2*num1);
    }else if(o.equals("/")){
    num1=(Double)numberStack.pop();
    num2=(Double)numberStack.pop();
    numberStack.push(num2/num1);
    }
    }
    resultNumber = (Double)numberStack.pop();
    
    return resultNumber;
    }
    
    public Double process(String equation){
    ArrayList postfix = infixToPostfix(splitTokens(equation));
    Double result = postFixEval(postfix);
    return result;
    }
    
    public boolean checkNumber(String str){
    char check;
    
    if(str.equals("")){
    return false;
    }
    
    for(int i=0;i<str.length();i++){
    check=str.charAt(i);
    if(check<48||check>58){
    if(check!='.')
    return false;
    }
    }
    
    return true;
    }
    
    }

     

    CalculatorHelper 클래스는 앞서 입력한 계산식을 후위 표기법으로 바꾼 후 연산을 실행한다. 

     

     

     

    CalculateHelper에는 splitTokens, infixToPostfix, postFixEval, process, checkNumber 함수가 있다.

     

     

    [CalculateHelper.splitTokens] : 연산식을 ArrayList에 담아 반환한다.

     

     

     

    jamanbbo.tistory.com/53

     

    [Stack]사칙연산 계산기 구현(1) - 후위 표기법

    사칙연산 계산기 구현 - 후위 표기법 사칙연산 프로그램을 만들 때 사용하는 수식의 표현법이다. 보통 우리가 사용하는 수식은 중위 표기법으로 표현된다. 중위 표기법은 연산자가 피연산자들��

    jamanbbo.tistory.com

    이 글을 보면 스택 계산기의 후위 표기법에 대해 아주 잘 나타나 있다. 

     

     

    [CalculateHelper.infixToPostfix] : 중위 표기법을 후위 표기법으로 바꾼다.

    private ArrayList infixToPostfix(ArrayList constant){
    ArrayList result= new ArrayList();
    HashMap level = new HashMap();
    Stack stack = new Stack();
    
    level.put("*",3);
    level.put("/",3);
    level.put("+",2);
    level.put("-",2);
    level.put("(",1);
    
    for(Object object : constant){
    if(object.equals(")")){
    stack.push(object);
    }else if(object.equals(")")){
    while(!stack.peek().equals("(")){
    Object val = stack.pop();
    if(!val.equals("(")){
    result.add(val);
    }
    }
    stack.pop();
    }else if(level.containsKey(object)){
    if(stack.isEmpty()){
    stack.push(object);
    }else{
    if(Double.parseDouble(level.get(stack.peek()).toString()) >= Double.parseDouble(level.get(object).toString())){
    result.add(stack.pop());
    stack.push(object);
    }else{
    stack.push(object);
    }
    }
    }else{
    result.add(object);
    }
    }
    while(!stack.isEmpty()){
    result.add(stack.pop());
    }
    return result;
    }

     

    해쉬맵을 통해 우선순위를 곱셈, 나눗셈은 3, 덧셈 뺄셈은 2, 여는 괄호는 1로 설정해놨다.

     

    if(object.equals(")")){
    stack.push(object);
    }else if(object.equals(")")){
    while(!stack.peek().equals("(")){
    Object val = stack.pop();
    if(!val.equals("(")){
    result.add(val);
    }
    }
    stack.pop();
    }

     

    여는 괄호가 나오면 무조건 스택에 넣고 닫는 괄호가 나오면 여는 괄호까지의 모든 내용을 pop 한다.

     

    else if(level.containsKey(object)){
    if(stack.isEmpty()){
    stack.push(object);
    }else{
    if(Double.parseDouble(level.get(stack.peek()).toString()) >= Double.parseDouble(level.get(object).toString())){
    result.add(stack.pop());
    stack.push(object);
    }else{
    stack.push(object);
    }
    }
    }else{
    result.add(object);
    }
    }
    while(!stack.isEmpty()){
    result.add(stack.pop());
    }

     

    우선순위가 높은게 나오면 pop해서 result에 추가하고 낮은걸 스택에 쌓는다.

     

     

     

    [CalculateHelper.postFixEval]: 후위표기법의 식을 계산한다.

     

     

    후위 표기법의 식을 탐색한다. 숫자가 나올경우 스택에 Push하고 연산자가 나올 경우 첫번째 pop한 수와 두번째로 pop

    한 수에 연산을 한다.

     

    [CalculateHelper.process]: 최종적으로 계산값을 리턴하는 함수

    public Double process(String equation){
    ArrayList postfix = infixToPostfix(splitTokens(equation));
    Double result = postFixEval(postfix);
    return result;
    }

     

     

    [CalculateHelper.checkNumber]: 아스키코드로 숫자인지 판별해 boolean값을 반환하는 함수 

    public boolean checkNumber(String str){
    char check;
    
    if(str.equals("")){
    return false;
    }
    
    for(int i=0;i<str.length();i++){
    check=str.charAt(i);
    if(check<48||check>58){
    if(check!='.')
    return false;
    }
    }
    
    return true;
    }

     

    5. 앱 아이콘 변경, 빌드

    다음으로 앱 아이콘을 바꾸고 빌드해보자.

     

    [File]-[New]-[Image Asset]을 클릭한다.

     

     

    Select Path로 이미지가 저장된 경로를 연다.

     

     

    이미지를 선택하고 적당한 크기로 조절한다.

     

    기존의 아이콘(좌)와 바뀐 아이콘(우)

    아이콘이 바뀌었음을 확인할 수 있다.

     

    https://developer.android.com/studio/run?hl=ko
    https://developer.android.com/studio/run?hl=ko

     

    이렇게 에뮬레이터 대신 실제 기기로 실행해보면 어플이 기기에 배포된다. Google Play에 공유, 업로드 할 앱을 빌드하려면 다음과 같이 하면 된다.

     

    [Build]-[Build Bundle(s) / APK(s)]-[Build APK(s)] 

     

     

Designed by Tistory.