Java/Android Studio

안드로이드 스튜디오 계산기(2): 레이아웃,버튼 추가, MainActivity

Choi G.H 2020. 9. 10. 17:31
반응형

※계산기 프로그램은 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로 옮긴다.

 

다음 글에서 CalculateHelper 클래스를 추가해보자 

 

반응형