본문 바로가기
Android Application/응용 구현

Android Studio 연습용 어플 구현2 (사용자 입력2)

by sdchjjj 2020. 5. 26.
728x90

안녕하세요! 오늘은 지난 포스팅에 이어 어플의 기능을 확장해 보겠습니다. 오늘 구현할 어플의 초기단계 제작은 다음 링크를 참고해 주세요. it-of-fortune.tistory.com/15

 

Android Studio 연습용 어플 구현2 (사용자 입력)

안녕하세요, 오늘도 새로운 예제를 가지고 공부를 하는 시간을 가져보도록 하겠습니다. 이전 시간에는 다수의 Activity를 사용해 앱을 만들어 봤는데요, 이번에는 하나의 Activity만 사용하게 됩니��

it-of-fortune.tistory.com

기존의 앱에서 메뉴의 수를 늘려 보고 그에 따른 여러 가지 내용 또한 추가하는 작업을 해보았습니다.

먼저 그 내용을 한번 알아보겠습니다.

 

사진1

우선은 Activity의 수는 그대로 한 개이고, UI가 조금 수정되었네요. 메뉴의 수가 늘어났으며 RESET 버튼이 새로 생겼습니다.

그 외에 자잘하게 텍스트가 변경된 사항도 있습니다.

 

사진2

이전과 마찬가지로 +를 누르면 수량과 가격이 늘어나고, -를 누르면 반대로 떨어지게 됩니다. 물론 menu마다 개별적으로 동작하고, TOTAL PRICE 아래에 총가격이 표시됩니다. ORDER은 여전히 아무런 기능도 하지 않는 장식이며 RESET을 누르면 모든 값이 처음처럼 0으로 돌아가게 됩니다.

 

먼저 layout 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"
    tools:context=".MainActivity"
    android:orientation="vertical">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/menu"
        android:textSize="25sp"
        android:layout_marginVertical="10dp"
        android:layout_gravity="center"/>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginVertical="10dp"
        android:orientation="horizontal">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginHorizontal="20dp"
            android:text="@string/first_menu"
            android:textSize="20sp" />

        <Button
            android:layout_width="40dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="20dp"
            android:onClick="reduceOrder1"
            android:text="@string/minus"
            android:textSize="15sp" />

        <TextView
            android:id="@+id/quantity_view1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="20dp"
            android:text="0"
            android:textSize="20sp" />

        <Button
            android:layout_width="40dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="20dp"
            android:onClick="plusOrder1"
            android:text="@string/plus"
            android:textSize="15sp" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="20dp"
            android:text="$"
            android:textSize="20sp" />

        <TextView
            android:id="@+id/price_view1"
            android:layout_width="wrap_content"
            android:layout_height="25dp"
            android:text="0"
            android:textSize="20sp" />

    </LinearLayout>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginVertical="10dp"
        android:orientation="horizontal">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginHorizontal="20dp"
            android:text="@string/second_menu"
            android:textSize="20sp" />

        <Button
            android:layout_width="40dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="20dp"
            android:onClick="reduceOrder2"
            android:text="@string/minus"
            android:textSize="15sp" />

        <TextView
            android:id="@+id/quantity_view2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="20dp"
            android:text="0"
            android:textSize="20sp" />

        <Button
            android:layout_width="40dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="20dp"
            android:onClick="plusOrder2"
            android:text="@string/plus"
            android:textSize="15sp" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="20dp"
            android:text="$"
            android:textSize="20sp" />

        <TextView
            android:id="@+id/price_view2"
            android:layout_width="wrap_content"
            android:layout_height="25dp"
            android:text="0"
            android:textSize="20sp" />

    </LinearLayout>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginVertical="10dp"
        android:orientation="horizontal">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginHorizontal="20dp"
            android:text="@string/third_menu"
            android:textSize="20sp" />

        <Button
            android:layout_width="40dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="20dp"
            android:onClick="reduceOrder3"
            android:text="@string/minus"
            android:textSize="15sp" />

        <TextView
            android:id="@+id/quantity_view3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="20dp"
            android:text="0"
            android:textSize="20sp" />

        <Button
            android:layout_width="40dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="20dp"
            android:onClick="plusOrder3"
            android:text="@string/plus"
            android:textSize="15sp" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="20dp"
            android:text="$"
            android:textSize="20sp" />

        <TextView
            android:id="@+id/price_view3"
            android:layout_width="wrap_content"
            android:layout_height="25dp"
            android:text="0"
            android:textSize="20sp" />

    </LinearLayout>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/total_price"
        android:textSize="25sp"
        android:layout_gravity="center"
        android:layout_marginVertical="10dp"/>

    <TextView
        android:id="@+id/total_price_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="0"
        android:textSize="20sp"
        android:layout_gravity="center"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:background="#FFFFFF"
        android:text="@string/order"
        android:textSize="20sp"
        android:layout_marginVertical="10dp"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="#FFFFFF"
        android:text="@string/reset"
        android:textSize="20sp"
        android:layout_gravity="center"
        android:onClick="reset"/>

</LinearLayout>

먼저 설명해 드릴 부분은 LinearLayout의 수가 늘어났습니다. 바로 menu TextView가 포함된 layout을 아래에다 똑같이 복사 붙여 넣기를 해주었기 때문입니다. 그렇게 해준 뒤 수량을 나타내는 TextView의 id를 바꿔 주었고, +, - 가 연결되어 있는 onClick부분의 메서드도 바꿔주었습니다. 마지막에 RESET을 나타내는 버튼 또한 추가되었습니다. 

 

여기서 android:text="@string" 이런 식으로 text의 값이 바뀐 것을 볼 수 있는데 이것은 res -> values -> strings.xml 파일 내에 해당 값을 선언해 준 뒤, 필요한 이름을 가져온다는 의미입니다. 잠시 string.xml 파일을 살펴보겠습니다. 

 

<resources>
    <string name="app_name">OrderMenu</string>
    <string name="plus">+</string>
    <string name="minus">-</string>
    <string name="order">ORDER</string>
    <string name="menu">MENU</string>
    <string name="total_price">TOTAL PRICE ($)</string>
    <string name="first_menu">menu 1 ($5)</string>
    <string name="second_menu">menu 2 ($7)</string>
    <string name="third_menu">menu 3 ($9)</string>
    <string name="reset">RESET</string>
</resources>

제 파일을 열어보면 이런 식으로 되어있는데 보이시는 바와 같이 name=" " 부분에 변수의 이름을 선언하고, 그 뒤에 실제로 표시하고 싶은 텍스트를 적으면 되는 것입니다. 그러고 난 후 위에 있는 layout xml 파일에서 처럼 android:text="@string/변수"와 같이 사용하면 뷰에는 해당 변수가 가지고 있는 값을 표기하게 됩니다.

 

layout에 관한 설명은 이 정도로 충분하다고 생각하니, 다음으로 넘어가겠습니다.

다음은 MainActivity 클래스 내용입니다.

 

package com.example.ordermenu;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private String lowestNumMessage = "가장 낮은 수량입니다.";
    private int menu1Num = 0;
    private int menu2Num = 0;
    private int menu3Num = 0;
    private int menu1Price = 0;
    private int menu2Price = 0;
    private int menu3Price = 0;
    private int checkNum= 0 ;

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

    public void plusOrder1(View view) {
        checkNum = 1;
        menu1Num++;
        displayMenuNum(menu1Num, checkNum);
    }

    public void plusOrder2(View view) {
        checkNum = 2;
        menu2Num++;
        displayMenuNum(menu2Num, checkNum);
    }

    public void plusOrder3(View view) {
        checkNum = 3;
        menu3Num++;
        displayMenuNum(menu3Num, checkNum);
    }

    public void reduceOrder1(View view) {
        if (menu1Num <= 0) {
            menu1Num = 0;
            Toast.makeText(this.getApplicationContext(), lowestNumMessage, Toast.LENGTH_SHORT).show();
            return;
        }
        checkNum = 1;
        menu1Num--;
        displayMenuNum(menu1Num, checkNum);
    }

    public void reduceOrder2(View view) {
        if (menu2Num <= 0) {
            menu2Num = 0;
            Toast.makeText(this.getApplicationContext(), lowestNumMessage, Toast.LENGTH_SHORT).show();
            return;
        }
        checkNum = 2;
        menu2Num--;
        displayMenuNum(menu2Num,checkNum);
    }

    public void reduceOrder3(View view) {
        if (menu3Num <= 0) {
            menu3Num = 0;
            Toast.makeText(this.getApplicationContext(), lowestNumMessage, Toast.LENGTH_SHORT).show();
            return;
        }
        checkNum = 3;
        menu3Num--;
        displayMenuNum(menu3Num, checkNum);
    }

    public void displayMenuNum(int num, int check) {
        if(check == 1) {
            TextView quantityView = findViewById(R.id.quantity_view1);
            quantityView.setText(String.valueOf(num));
            displaySinglePrice(num, check);
        }
        else if(check == 2) {
            TextView quantityView = findViewById(R.id.quantity_view2);
            quantityView.setText(String.valueOf(num));
            displaySinglePrice(num, check);
        }
        else if(check == 3) {
            TextView quantityView = findViewById(R.id.quantity_view3);
            quantityView.setText(String.valueOf(num));
            displaySinglePrice(num, check);
        }
    }

    public void displaySinglePrice(int num, int check) {
        int price;
        if(check == 1) {
            price = 5;
            menu1Price = num * price;
            TextView quantityView = findViewById(R.id.price_view1);
            quantityView.setText(String.valueOf(menu1Price));
            displayTotalPrice();
        }
        else if(check == 2) {
            price = 7;
            menu2Price = num * price;
            TextView quantityView = findViewById(R.id.price_view2);
            quantityView.setText(String.valueOf(menu2Price));
            displayTotalPrice();
        }
        else if(check == 3) {
            price = 9;
            menu3Price = num * price;
            TextView quantityView = findViewById(R.id.price_view3);
            quantityView.setText(String.valueOf(menu3Price));
            displayTotalPrice();
        }
    }

    public void displayTotalPrice() {
        int totalPrice = menu1Price + menu2Price + menu3Price;
        TextView quantityView = findViewById(R.id.total_price_view);
        quantityView.setText(String.valueOf(totalPrice));
    }

    public void reset(View view) {
        for(int i = 1; i <= 3; i++) {
            displayMenuNum(0, i);
            displaySinglePrice(0,i);
        }
        menu1Num = 0;
        menu2Num = 0;
        menu3Num = 0;
    }
}

 

가장 먼저 보이는 것은 여러 가지 변수가 늘어났습니다. 각각의 메뉴의 수량을 나타내는 menu1,2,3Num. 가격을 나타내는 menu1,2,3Price. 그리고 checkNum이 추가되었습니다. 각각의 메뉴에서 동작하는 원리는 같으니, menu1의 동작을 대표로 설명해 드리겠습니다.

 

먼저 +를 누르거나 -를 누르면 menu1Num의 수량이 늘어나거나 줄어듭니다. -의 경우에는 지난번처럼 0 아래로 떨어지면 팝업 메시지를 띄우며 더 이상 내려가지 않습니다. 그리고 또한 가지 작업은 바로 checkNum의 값을 바꿔주는 것입니다. menu1의 경우 checkNum의 값은 1로 저장되어 displayMenuNum 메서드를 menu1Num값과 함께 인자로 전달하며 호출합니다.

 

menu1Num과 checkNum 값을 받으며 호출된 displayMenuNum 메서드는 checkNum값을 자신의 check변수에 저장하며 값을 비교하기 시작합니다. 현재는 check의 값으로 1을 전달받았으니 첫 번째 if문이 실행되게 됩니다. 

 

첫 번째 if문에서 menu 1의 수량을 표기해 주는 작업을 한 뒤, displaySinglePrice를 부릅니다. 이번에도 역시 수량이 저장되어 있는 num과 1이 저장되어 있는 check를 넘겨줍니다.

 

displaySinglePrice는 처음에 int price; 로 변수를 선언하고, check의 값에 1이 들어있으므로 위에서와 같이 첫 번째 if문을 실행합니다. 그곳에서 price의 값은 첫 번째 메뉴의 가격인 5가 저장되고, menu1Price에 num과 price를 곱해 menu 1의 총가격을 계산합니다. 그리고 그 결과를 menu 1의 가장 오른쪽에 있는 가격이 표시되는 부분에 뿌려줍니다. 턴을 마친 displaySinglePrice는 displayTotalPrice를 부릅니다. 이번에는 아무런 값도 인자로 전달하지 않고 그냥 부릅니다.

 

불려 온 displayTotalPrice 메서드는 totalPrice를 선언한 뒤 그곳에 menu1Price, menu2Price, menu3Price를 모두 더한 값을 저장합니다. 그리고 그 결과를 total price를 나타내는 뷰에 뿌려줍니다.  

 

이제 거의 다 왔군요. 지금까지의 설명에서 사실 checkNum은 큰 역할을 하지 않았습니다. 전역 변수로 선언되어있기 때문에 어떤 메서드에서도 사용할 수 있기 때문에 굳이 인자로 넘겨주지 않아도 동작에는 전혀 지장이 없습니다. 그럼에도 인자로 받게끔 한 이유는 reset을 구현하기 위해서입니다.

 

마지막에 reset을 보면 for문으로 loop를 구현해 놨는데 i는 1부터 시작해서 3까지 돌게 됩니다. 루프를 돌면서 메뉴의 수량과 가격을 나타내는 메서드들에게 각각 수량을 0개로, 메뉴 1,2,3을 나타내는 CheckNum을 전달하는 부분에 i 값을 주어 모든 메뉴의 수량을 0으로 만들어 주는 작업을 하고 있습니다. for문을 나온 뒤 수량이 실제로 저장되어 있는 menu1,2,3Num 또한 0으로 모두 바꿔주면 reset의 작업이 끝나게 됩니다.

 

자 이렇게 지난번에 이어 앱의 확장공사를 마무리하게 되었습니다. 이보다 더 간결하고 깔끔하고, 효율적인 앱이 분명 있을 거라 생각하고, 작업을 마친 지금도 몇 가지 생각나는 아이디어가 있는데 모두 수월하게 앱을 구현하실 수 있으리라 믿습니다. 그럼 오늘 포스팅은 여기서 마치겠습니다!

728x90

댓글