안드로이드 스튜디오 계산기 중급 (onClick)

안드로이드 스튜디오 계산기 중급 (onClick)

Author : Jino Bae / Send Mail

이전글에서는 클릭 리스너를 생성하는 과정만 다뤘으나 이번에는 XML에서 onClick을 구현하는 과정도 다루고 있습니다. 클릭 리스너를 생성하는 것이 일반적인 경우지만 때에따라 onClick으로 구현하는 경우가 효율적일 수 있습니다.


이번 계산기는 테이블 레이아웃을 이용하여 숫자 자판을 직접 구현할 것입니다. 아래는 완성된 계산기의 동작 화면입니다.





Layout

이번에도 레이아웃을 먼저 설계할 것이며, 레이아웃은 Text 탭에서 벗어나는 경우는 없습니다. 가장 외각에 사용되는 레이아웃은 TableLayout입니다. 테이블 레이아웃에는 각각의 TableRow가 존재하며 TableRow 안에 위젯을 원하는 크기로 배치할 수 있습니다.



이전 소스코드를 이해하셨다면 이번에도 이해하는데 큰 문제가 없습니다. 반복되는 부분이 많아서 길어 보이는 것 뿐입니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
    <TableLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center">
        <TableRow android:gravity="center">
            <TextView
                android:id="@+id/Label1"/>
        </TableRow>
        <TableRow android:gravity="center">
            <EditText
                android:id="@+id/Edit1"
                android:hint="숫자를 입력하시오."
                android:layout_span="4"
                />
        </TableRow>
        <TableRow android:gravity="center">
            <EditText
                android:id="@+id/Edit2"
                android:hint="숫자를 입력하시오."
                android:layout_span="4"
                />
        </TableRow>
        <TableRow android:gravity="center">
            <Button
                android:onClick="Numbering"
                android:id="@+id/Num1"
                android:text="1"/>
            <Button
                android:onClick="Numbering"
                android:id="@+id/Num2"
                android:text="2"/>
            <Button
                android:onClick="Numbering"
                android:id="@+id/Num3"
                android:text="3"/>
            <Button
                android:id="@+id/Add"
                android:text="+"/>
        </TableRow>
        <TableRow android:gravity="center">
            <Button
                android:onClick="Numbering"
                android:id="@+id/Num4"
                android:text="4"/>
            <Button
                android:onClick="Numbering"
                android:id="@+id/Num5"
                android:text="5"/>
            <Button
                android:onClick="Numbering"
                android:id="@+id/Num6"
                android:text="6"/>
            <Button
                android:id="@+id/Sub"
                android:text="-"/>
        </TableRow>
        <TableRow android:gravity="center">
            <Button
                android:onClick="Numbering"
                android:id="@+id/Num7"
                android:text="7"/>
            <Button
                android:onClick="Numbering"
                android:id="@+id/Num8"
                android:text="8"/>
            <Button
                android:onClick="Numbering"
                android:id="@+id/Num9"
                android:text="9"/>
            <Button
                android:id="@+id/Mul"
                android:text="*"/>
        </TableRow>
        <TableRow android:gravity="center">
            <Button
                android:onClick="Numbering"
                android:id="@+id/Num0"
                android:text="0"
                android:layout_span="2"/>
            <Button
                android:id="@+id/Next"
                android:text="Next"/>
            <Button
                android:id="@+id/Div"
                android:text="/"/>
        </TableRow>
    </TableLayout>

기억해두면 좋은 것은 layout_span이라는 옵션입니다. 보다시피 다른 위젯보다 더 크게 만들 수 있습니다. 그리고 onClick="Numbering"이라는 옵션이 보입니다. 모든 숫자 패드가 같은 함수를 호출하고 있습니다. 소스코드에서 어떻게 활용되는지 살펴보겠습니다.


Java

객체를 생성하고 아이디를 읽어오도록 하겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class MainActivity extends AppCompatActivity {

    Button Add,Sub,Mul,Div,Next;
    EditText Edit1, Edit2;
    TextView Label1;
    String Number1, Number2;
    Integer I_Number1, I_Number2, Result;
    boolean NextEdit = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Edit1 = (EditText) findViewById(R.id.Edit1);
        Edit2 = (EditText) findViewById(R.id.Edit2);
        Add = (Button) findViewById(R.id.Add);
        Sub = (Button) findViewById(R.id.Sub);
        Mul = (Button) findViewById(R.id.Mul);
        Div = (Button) findViewById(R.id.Div);
        Next = (Button) findViewById(R.id.Next);
        Label1 = (TextView)findViewById(R.id.Label1);
    }
}

또 눈에 띄는 부분은 숫자패드 부분은 전혀 생성하지도 읽어오지도 않았다는 것입니다. 먼저 Numbering 메소드가 어떻게 구현할지 만들어 보도록 하겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
 public void Numbering(View v){
        switch (v.getId())
        {
            case R.id.Num0:
                Edit1.append("0");
                break;
            case R.id.Num1:
                Edit1.append("1");
                break;
            case R.id.Num2:
                Edit1.append("2");
                break;
            case R.id.Num3:
                Edit1.append("3");
                break;
            case R.id.Num4:
                Edit1.append("4");
                break;
            case R.id.Num5:
                Edit1.append("5");
                break;
            case R.id.Num6:
                Edit1.append("6");
                break;
            case R.id.Num7:
                Edit1.append("7");
                break;
            case R.id.Num8:
                Edit1.append("8");
                break;
            case R.id.Num9:
                Edit1.append("9");
                break;
        }
    }

위와같이 View 객체를 가져와 switch를 통해서 각각의 아이디를 판단하고 숫자를 넣어주는 방식으로 구현하였습니다. 더 좋은 방법이 있다면 그렇게 하시고 저도 알려주세요!


다만 이렇게 구현하면 하나의 텍스트 에디터에만 넣을 수 있게됩니다. 제가 NEXT 버튼을 만든 이유가 바로 이것 때문입니다. NEXT 버튼을 누르면 boolean 변수인 NextEdit의 값이 변하고 이를 감지하여 텍스트 에디터를 옮겨가며 숫자를 넣을 수 있게됩니다.

1
2
3
4
5
6
        Next.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                NextEdit = !NextEdit;
            }
        });
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
 public void Numbering(View v){
        switch (v.getId())
        {
            case R.id.Num0:
                if(NextEdit==false) Edit1.append("0");
                else Edit2.append("0");
                break;
            case R.id.Num1:
                if(NextEdit==false) Edit1.append("1");
                else Edit2.append("1");
                break;
            case R.id.Num2:
                if(NextEdit==false) Edit1.append("2");
                else Edit2.append("2");
                break;
            case R.id.Num3:
                if(NextEdit==false) Edit1.append("3");
                else Edit2.append("3");
                break;
            case R.id.Num4:
                if(NextEdit==false) Edit1.append("4");
                else Edit2.append("4");
                break;
            case R.id.Num5:
                if(NextEdit==false) Edit1.append("5");
                else Edit2.append("5");
                break;
            case R.id.Num6:
                if(NextEdit==false) Edit1.append("6");
                else Edit2.append("6");
                break;
            case R.id.Num7:
                if(NextEdit==false) Edit1.append("7");
                else Edit2.append("7");
                break;
            case R.id.Num8:
                if(NextEdit==false) Edit1.append("8");
                else Edit2.append("8");
                break;
            case R.id.Num9:
                if(NextEdit==false) Edit1.append("9");
                else Edit2.append("9");
                break;
        }
    }


자 여기까지 완성했다면 저번 포스트에서 구현한 기능을 이용하여 덧셈, 뺄셈, 곱셈, 나눗셈을 구현할 수 있게됩니다. 다만 저번 포스트에선 아무런 예외를 처리하지 않고 단지 기능만 구현했습니다. 이번에는 몇가지의 예외를 if를 통해서 처리하도록 하겠습니다.


더하기 버튼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
        Add.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(Edit1.getText().length()==0 || Edit2.getText().length()==0) {
                    Toast.makeText(MainActivity.this, "공백을 둘 수 없습니다.", Toast.LENGTH_SHORT).show();
                }
                else {
                    Number1 = Edit1.getText().toString();
                    Number2 = Edit2.getText().toString();
                    I_Number1 = Integer.parseInt(Number1);
                    I_Number2 = Integer.parseInt(Number2);
                    Result = I_Number1+I_Number2;
                    Label1.setText(Result.toString());
                    Edit1.setText("");
                    Edit2.setText("");
                }
            }
        });

else 부분은 저번에 구현한 기능과 거의 동일합니다. 결과를 처리하고 에디터의 내용을 지워주는 것만 바꾸었습니다. 주의깊게 봐야 할 부분은 if 입니다. 에디터의 내용중에 하나라도 빈 값이 있으면 처리하지 않고 Toast를 출력합니다.


뺄셈과 곱셈은 위와 완전히 동일하므로 넘어가도록 하겠습니다.


나누기 버튼

나누기 버튼은 위 3가지 버튼보다 예외인 상황이 하나가 더 있습니다. 나눗셈은 0으로 나눌 수 없습니다. 따라서 Edit2가 0인 경우 한번더 메세지를 띄워주어야 할 필요가 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
        Div.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(Edit1.getText().length()==0 || Edit2.getText().length()==0) {
                    Toast.makeText(MainActivity.this, "공백을 둘 수 없습니다.", Toast.LENGTH_SHORT).show();
                }
                else if(Edit2.getText().toString().equals("0")){
                    Toast.makeText(MainActivity.this, "0으로 나눌 수 없습니다.", Toast.LENGTH_SHORT).show();
                }
                else {
                    Number1 = Edit1.getText().toString();
                    Number2 = Edit2.getText().toString();
                    I_Number1 = Integer.parseInt(Number1);
                    I_Number2 = Integer.parseInt(Number2);
                    Result = I_Number1/I_Number2;
                    Label1.setText(Result.toString());
                    Edit1.setText("");
                    Edit2.setText("");
                }
            }
        });

이제 어플리케이션을 실행해 보세요. 정상적으로 연산 결과가 레이블에 출력되는 것을 확인할 수 있습니다.



Jino Bae
WRITTEN BY

Jino Bae

Digital is a purely man-made playground. That's why I like.
im@baejino.com


comments powered by Disqus