-
안드로이드 스튜디오 계산기(2): 레이아웃,버튼 추가, MainActivityJava/Android Studio 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>LinearLayout─LinearLayout─ScrollView─first_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 클래스를 추가해보자
'Java > Android Studio' 카테고리의 다른 글
공공데이터 API 요청 보내고 응답 받기 (0) 2021.07.17 액티비티 간 전환하기 (2) 2021.06.27 pt.1~3)안드로이드 스튜디오 계산기 (프로젝트 생성부터 완성까지!) (3) 2020.09.10 안드로이드 스튜디오 계산기(3): CalculateHelper 클래스 추가, 빌드 (0) 2020.09.10 안드로이드 스튜디오 계산기(1): 프로젝트 생성, 에뮬레이터 실행 (0) 2020.09.10