ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 안드로이드 스튜디오 계산기(2): 레이아웃,버튼 추가, MainActivity
    Java/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>

     

    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 클래스를 추가해보자 

     

Designed by Tistory.