본문 바로가기
안드로이드

패스트캠퍼스 안드로이드 앱 강의 후기 3 - BMI 계산기 어플

by 디토20 2022. 3. 21.
반응형

패스트캠퍼스 안드로이드 앱 강의 후기 3 - BMI 계산기

 

 

part2 Basic의 챕터 1인 BMI 계산기 만들기를 시작했다.

 

첫 코드는 아래와 같다.

 

res/layout/activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <TextView
        android:text="신장"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:inputType="number"/>

    <TextView
        android:id="@+id/textView2"
        android:text="체중"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <EditText
        android:id="@+id/editTextNumber"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:inputType="number"/>
    <Button
        android:text="확인하기"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

</LinearLayout>

 

 

안드로이드 스튜디오는 프로젝트를 생성하면

acticity_main.xml 파일이 기본적으로 constraintlayout으로 되어있는데

첫 강의에서는 LinearLayout 으로 만드는 법을 배웠다.

 

LinearLayout 이란 아이템들이 차곡차곡 쌓이는 것을 말하는데

android:orientation="vertical"

일 경우는 위부터 아래로 차곡차곡 쌓이게 되고,

 

android:orientation="horizontal"

일 경우에는 왼쪽부터 오른쪽으로 차곡차곡 쌓이게 된다!

 

 

 

<TextView
    android:text="신장"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>

 

TextView는

텍스트를 입력하면 입력한대로 출력이 되고

 

 

<EditText
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:inputType="number"/>

 

EditText는

어플 내에서 값을 직접 입력, 수정 할수 있는 아이템이다

inputType을 지정해 줄 수 있는데,

지정을 안해주면 영문 키패드가 기본으로 뜨고

number로 지정해주면 숫자 키패드가 기본으로 뜨며

숫자만 입력이 가능하다.

 

number 외에도 다양한 기능이 있다

 

 

위의 코드를 작성하면

이렇게 텍스트들이 딱 붙어서 나오기 때문에

 디자인 요소를 넣어주었다.

 

 


res/layout/activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp"
    tools:context=".MainActivity">

    <TextView
        android:textColor="@color/custom_black"
        android:textStyle="bold"
        android:textSize="20sp"
        android:text="@string/height"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <EditText
        android:layout_marginTop="10dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:inputType="number"/>

    <TextView
        android:textColor="@color/custom_black"
        android:textStyle="bold"
        android:textSize="20sp"
        android:layout_marginTop="30dp"
        android:id="@+id/textView2"
        android:text="@string/weight"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <EditText
        android:layout_marginTop="10dp"
        android:id="@+id/editTextNumber"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:inputType="number"/>
    <Button
        android:layout_marginTop="50dp"
        android:text="@string/confirm"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

</LinearLayout>

padding과 text style을 적용해 주었다.

text 값 같은 경우는

"확인"과 같은 하드코딩에서

strings.xml을 이용해 name값을 넣어주었고

color도 역시 colors.xml을 이용해 값을 넣어주었다.

 

res/values/colors.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="purple_200">#FFBB86FC</color>
    <color name="purple_500">#FF6200EE</color>
    <color name="purple_700">#FF3700B3</color>
    <color name="teal_200">#FF03DAC5</color>
    <color name="teal_700">#FF018786</color>
    <color name="black">#FF000000</color>
    <color name="custom_black">#222222</color>
    <color name="white">#FFFFFFFF</color>
</resources>

 

 

res/values.strings.xml

<resources>
    <string name="app_name">aop-part2-chapter01</string>
    <string name="height">신장</string>
    <string name="weight">체중</string>
    <string name="confirm">확인하기</string>
</resources>

 

 

 

 

 

그러면 조금은 정리된

아래와 같은 화면을 볼 수 있다

(사실 이것도 못생겼음)

 


이제 기능을 넣어주자!

 

 

 

코드를 입력하고

Ctrl + Alt + L 을 누르면

코드가 알아서 예쁘게 정렬된다.

 

 

res/layout/activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/height"
        android:textColor="@color/custom_black"
        android:textSize="20sp"
        android:textStyle="bold" />

    <EditText
        android:id="@+id/heightEditText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:inputType="number" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:text="@string/weight"
        android:textColor="@color/custom_black"
        android:textSize="20sp"
        android:textStyle="bold" />

    <EditText

        android:id="@+id/weightEditText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:ems="10"
        android:inputType="number" />

    <Button
        android:id="@+id/resultButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="50dp"
        android:text="@string/confirm" />

</LinearLayout>

기능을 넣어주기 위해선

내가 사용할 컴포넌트들에 아이디를 선언해줘야 한다.

그래서 EditText와 Button에 각각 이름을 선언해주었다.

 

그 후 java의 MainActivity를 수정해주었다.

 

 

java/fastcampus/aop_part2_chapter01/MainActivity

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val heightEditText : EditText = findViewById(R.id.heightEditText) // 변수 타입 선언 시 findViewById의 타입을 선언 할 필요 X
        val weightEditText = findViewById<EditText>(R.id.weightEditText)// 변수 타입 미선언 시 findViewById의 타입을 선언 해줘야 함

        val resultButton = findViewById<Button>(R.id.resultButton)

        resultButton.setOnClickListener {
            if(heightEditText.text.isEmpty() || heightEditText.text.isEmpty()){
                Toast.makeText(this, "빈 값이 있습니다.", Toast.LENGTH_SHORT).show()
                return@setOnClickListener
            }

            // 이 아래로는 절대 빈값이 올 수 없음
            val height = heightEditText.text.toString().toInt()
            val weight = weightEditText.text.toString().toInt()

            val intent = Intent(this, ResultActivity::class.java)
            intent.putExtra("height", height)// 다음 activity에 데이터 넘겨주기
            intent.putExtra("weight", weight)
            startActivity(intent)
        }

    }
}

첫번째로 기능구현에 사용하고자 하는 변수들을 선언해주었다.

그 후 resultButton을 클릭하면 이벤트가 발생하는 람다함수를 작성했다.

 

if문이 필요한 이유는

textEdit의 text가 empty일 경우 toInt()에서 오류가 나기때문에

 

toInt()함수 사용 전에

값이 비었는지 안비었는지를 체크 해서

값이 비었을 경우 메세지를 출력하고 클릭 리스너를 빠져나갈 수 있게 해주었다.

 

 그 후 ResultActivity로 이동해

결과 값을 출력해 줄수 있게 해주는 코드를 작성했다.

 

 

 

java/fastcampus/aop_part2_chapter01/ResultActivity

class ResultActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_result)
    }
}

 

res/layout/activity_result.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

</androidx.constraintlayout.widget.ConstraintLayout>

Result 페이지를 띄우기 위해서

ResultActivity와 activity_result.xml를 생성해주고

생성된 activity를 등록해주었다.

 

 

manifests/AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="fastcampus.aop_part2_chapter01">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.Aoppart2chapter01">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".ResultActivity"/>
    </application>

</manifest>

이 과정을 안거치면 안드로이드 어플은 ResultActivity를 찾을 수 없어 오류가 나게 된다!

 

fastcampus 강의 별로라는 사람들 많았는데

어떤 경우에 오류가 나고 어떤식으로 디버깅 하는지

잘 알려줘서

아직까지는 생각보다 괜찮은 듯?

 

 

 


java/fastcampus/aop_part2_chapter01/ResultActivity

class ResultActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_result)

        val height = intent.getIntExtra("height", 0)
        val weight = intent.getIntExtra("weight", 0)

        val bmi = weight / (height / 100.0).pow(2.0)
        val resultText = when {
            bmi >= 35.0 -> "고도 비만"
            bmi >= 30.0 -> "중정도 비만"
            bmi >= 25.0 -> "경도 비만"
            bmi >= 23.0 -> "과체중"
            bmi >= 18.5 -> "정상체중"
            else -> "저체중"
        }
        val resultValueTextView = findViewById<TextView>(R.id.bmiResultTextView)
        val resultStringTextView = findViewById<TextView>(R.id.resultTextView)

        resultValueTextView.text = bmi.toString()
        resultStringTextView.text = resultText
    }
}

신장과 몸무게를 getIntExtra로 받아서 변수에 저장 후

bmi를 계산해 준다

bmi별 비만도를 when 분기문을 통해 resultText에 저장했다.

 

그 후 변수에 activity_result의 결과값 변수 id에 매핑해준 후

매핑 된 변수에 bmi와 resultText를 넣어주었다.

 

 

 

res/layout/activity_result.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:gravity="center"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="BMI : " />

        <TextView
            android:id="@+id/bmiResultTextView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text=""
            tools:text="23.1111" />

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="결과는 : " />

        <TextView
            android:id="@+id/resultTextView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="과체중입니다." />

    </LinearLayout>

</LinearLayout>

 

LinearLayout안에 LinearLayout을 넣어서 병렬 구조로 만들어 주었다

그 후 gravity로 가운데 정렬을 해주었다

 

tools:text는 빌드화면에는 안보이지만,

IDE의 design에서만 보이게 하는 기능이다!

 

 

 

 

 


최종 코드와 결과 !!

 

 

 

 

 

java/fastcampus/aop_part2_chapter01/MainActivity

package fastcampus.aop_part2_chapter01

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Button
import android.widget.EditText
import android.widget.Toast

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val heightEditText : EditText = findViewById(R.id.heightEditText) // 변수 타입 선언 시 findViewById의 타입을 선언 할 필요 X
        val weightEditText = findViewById<EditText>(R.id.weightEditText)// 변수 타입 미선언 시 findViewById의 타입을 선언 해줘야 함

        val resultButton = findViewById<Button>(R.id.resultButton)

        resultButton.setOnClickListener {
            if(heightEditText.text.isEmpty() || heightEditText.text.isEmpty()){
                Toast.makeText(this, "빈 값이 있습니다.", Toast.LENGTH_SHORT).show()
                return@setOnClickListener
            }

            // 이 아래로는 절대 빈값이 올 수 없음
            val height = heightEditText.text.toString().toInt()
            val weight = weightEditText.text.toString().toInt()

            val intent = Intent(this, ResultActivity::class.java)
            intent.putExtra("height", height)// 다음 activity에 데이터 넘겨주기
            intent.putExtra("weight", weight)
            startActivity(intent)
        }

    }
}

 

java/fastcampus/aop_part2_chapter01/ResultActivity

package fastcampus.aop_part2_chapter01

import android.os.Bundle
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import kotlin.math.pow

class ResultActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_result)

        val height = intent.getIntExtra("height", 0)
        val weight = intent.getIntExtra("weight", 0)

        val bmi = weight / (height / 100.0).pow(2.0)
        val resultText = when {
            bmi >= 35.0 -> "고도 비만"
            bmi >= 30.0 -> "중정도 비만"
            bmi >= 25.0 -> "경도 비만"
            bmi >= 23.0 -> "과체중"
            bmi >= 18.5 -> "정상체중"
            else -> "저체중"
        }
        val resultValueTextView = findViewById<TextView>(R.id.bmiResultTextView)
        val resultStringTextView = findViewById<TextView>(R.id.resultTextView)

        resultValueTextView.text = bmi.toString()
        resultStringTextView.text = resultText
    }
}

java/fastcampus/aop_part2_chapter01/ResultActivity

 

res/layout/activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/height"
        android:textColor="@color/custom_black"
        android:textSize="20sp"
        android:textStyle="bold" />

    <EditText
        android:id="@+id/heightEditText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:inputType="number" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:text="@string/weight"
        android:textColor="@color/custom_black"
        android:textSize="20sp"
        android:textStyle="bold" />

    <EditText

        android:id="@+id/weightEditText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:ems="10"
        android:inputType="number" />

    <Button
        android:id="@+id/resultButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="50dp"
        android:text="@string/confirm" />

</LinearLayout>

 

res/layout/activity_result.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:gravity="center"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="BMI : " />

        <TextView
            android:id="@+id/bmiResultTextView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text=""
            tools:text="23.1111" />

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="결과는 : " />

        <TextView
            android:id="@+id/resultTextView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="과체중입니다." />

    </LinearLayout>

</LinearLayout>

 

res/values/colors.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="purple_200">#FFBB86FC</color>
    <color name="purple_500">#FF6200EE</color>
    <color name="purple_700">#FF3700B3</color>
    <color name="teal_200">#FF03DAC5</color>
    <color name="teal_700">#FF018786</color>
    <color name="black">#FF000000</color>
    <color name="custom_black">#222222</color>
    <color name="white">#FFFFFFFF</color>
</resources>

 

 

res/values/strings.xml

<resources>
    <string name="app_name">aop-part2-chapter01</string>
    <string name="height">신장</string>
    <string name="weight">체중</string>
    <string name="confirm">확인하기</string>
</resources>

 

 

 

manifests/AndroidManifest.xml

 

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="fastcampus.aop_part2_chapter01">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.Aoppart2chapter01">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".ResultActivity"/>
    </application>

</manifest>

 

 

뿌듯-

 

 

728x90
반응형

댓글