티스토리 뷰

Android

[Android] 기초 1 in Kotlin

DevJunku 2021. 11. 18. 00:44

담화 어플을 제작할 때 처음으로 시작한 안드로이드였는데, 그때는 코틀린 배우기도 급급했습니다. OOP나 함수형 언어를 배우는게 처음은 아니지만, 뭔가 익숙하지 않은 느낌..... 역시 저는 꾸준히 공부를 해야하는 사람인거 같습니다. 모두 다 장기기억으로 돌려야죠!!

오늘은 Android에 대해 처음으로 포스팅하겠습니다. Basic한 부분을 다루겠습니다.


xml 관련

layout folder → 폴더명은 activity와 반대로 해주되, 대문자는 없게 하고 snake_case로 만들자.

컴포넌트의 기본 속성

layout_width: layout의 width를 결정
layout_height: layout의 height를 결정

  • match_parent: 부모 컴포넌트의 layout과 동일하다.
  • wrap_content: 컨텐츠의 크기 만큼만 layout의 크기가 할당된다.
    → 웬만하면 이렇게 주자. 왜냐면, 폰 마다 크기가 다르기 때문에..
    layout_margin: 마진을 준다. (start, end, top, bottom으로 나눌 수 있다.)
    padding: content의 크기 내에서만 마진을 주는 것과 같은 이치이다.
    • (content의 크기가 커지는 것은 아니다. start, end, bottom, top이 역시 존재한다.)
      id="@+id/&&&": id명을 지정해서 사용하며 findViewById(R.id.&&&)로 불러와서 사용할 수 있다.
오늘 배운 컴포넌트

TextView: text를 표현하기 위해서 사용 / html 태그와 같다.
- 생성하면 그냥 안의 text 속성은 무조건 문자열(string)이다. "" char가 아니다.
Button: Button을 표현하기 위해서 사용 / html 태그와 같다.
EditText: 텍스트를 입력하는 것이며, inputType로 해당 타입을 결정하여 키보드 판을 결정해줄 수 있다.

오늘 배운 Layout

LinearLayout: 컴포넌트들이 한 줄씩 배열할 수 있도록 해주는 태그 → orientation에서 vertical인지 horizontal인지 알려줘야한다.
- LinearLayout안에 LinearLayout을 만들 수 있음 → justify-content나 align-items와 같은 역할을 함
- gravity: LinearLayout의 컴포넌트를 이동시킬 수 있는 속성 → 여기서는 center를 사용함

values 폴더

colors: 색의 리소스를 관리하는 파일로 <color name="">색명<color>으로 표현할 수 있다.
string: layout의 string을 표현하기 위해 사용하는 파일로 <string name="">TEXT<string>으로 표현할 수 있다.

- 일반적으로 반복되는 부분을 줄이기 위해서 사용한다.
- 색도 글자도 반복되는 부분이 많으면 나중에 유지보수 하기 힘들기 때문에!
- 그리고 layout에서는 text나 textColor속성에서 `"@colors/name"`, `"@strings/name"`으로 표현하면 된다.

AndroidManifest

안드로이드 프로젝트의 전체적인 구성을 담당하는 곳 → activity 늘어나면 꼭 추가해주자. (주의: 순서 중요함)


activity 관련

파일명은 꼭 뒤에 activity써주기 일반적으로 CamelCase를 사용한다. (첫 글자 꼭 대문자로 쓰자.)
일반적으로 activity는 AppCompatActivity class를 상속받아서 사용한다.

onCreate: 가장 처음으로 실행되는 생명주기로 알고 있다. (아직 생명 주기 부분 빈약함.. 다시 알아보자.)
setContentView: 이거로 layout의 모든 정보를 갖고오는 것으로 알고 있다. (R.layout.layout_파일명)

activity에서 layout component의 id를 가져와서 사용하는 findViewById가 있다. (모두 widget임, 단 선언할 때 꼭 속성을 입력해야 하는 것을 잊지말자. 그리고 R.id.id명으로 가져온 component가 많아지면 사용하기 힘들다.. 그리고 많이 쓰면 안좋다고 들었다.)

한편으로 아래와 같이 findViewById를 사용할 수 있다. 둘 다 동일하게 해당 id의 component를 가져온다.

        val heightEditText: EditText = findViewById(R.id.heightEditText) // 선언 후 할당
        val weightEditText = findViewById<EditText>(R.id.weightEditText) // 할당하면서 선언, 어차피 똑같다.

오늘 배운 event

setOnClickListener: 클릭했을 때 무엇을 할지 알려주는 것
- 물론 findViewById를 사용해서 component를 할당했을 때 사용해야 한다.

Intent: 클릭을 눌렀을 때 특정 값을 다른 activity에 넘겨줘야할 때 intent를 사용함

Intent를 사용할 때의 특징
  1. 엑티비티 시작 (AndroidManifest.xml에 넘겨줄 Activity가 꼭 있어야함.
  2. 서비스 시작
  3. 브로드스트 시작
사용하는 법
val intent = Intent(this, NameActivity::class.java) // 넘겨줄 activity를 정하자.

// 아래를 추가하자
intent.putExtra("name1", name1)
intent.putExtra("name2", name2)

// NameActivity 실행! 
startActivity(intent)

넘겨받은 intent의 사용

intent.get변수종류Extra // ex) getIntIntent

val height = intent.getIntExtra("height", 0) // 넘겨준 intent의 이름과 default값을 입력한다.
val weight = intent.getIntExtra("weight", 0)

// 이후 바인딩 하고 싶은 component를 모두 findViewBy로 찾는다.
// 그리고 해당 값을 text속성이든 다른 속성이든 넘어주면 되겠다.
// 이때 중요한 건 역시 변수 타입이다. (꼭 헷갈리지 말자.)

오늘 작성한 코드의 전문

MainActivity

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
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)
        val weightEditText = findViewById<EditText>(R.id.weightEditText)

        val resultButton: Button = findViewById(R.id.resultButton)

        resultButton.setOnClickListener {

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

            // 이 아래로는 절대 빈 값이 올 수 없음.

            val height: Int = heightEditText.text.toString().toInt()
            val weight: Int = weightEditText.text.toString().toInt()

            // 클릭을 눌렀을 때 체중과 신장 값을 넘겨줘야하기 때문에 intent를 사용함
            // 1. 엑티비티 시작 (AndroidManifest.xml에 넘겨줄 Activity가 꼭 있어야함.
            // 2. 서비스 시작
            // 3. 브로드스트 시작
            val intent = Intent(this, ResultActivity::class.java)

            intent.putExtra("height", height)
            intent.putExtra("weight", weight)

            startActivity(intent)
        }
    }
}

ResultActivity

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 resultNumberTextView = findViewById<TextView>(R.id.resultNumberTextView)
        val resultStringTextView = findViewById<TextView>(R.id.resultStringTextView)

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

acitivity_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">
    <!--  LinearLayout하게 들어간다 -> 겹겹이 층으로(가로, 세로) 들어간다  -->
    <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/textView"
        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="30dp"
        android:text="확인하기" />

</LinearLayout>

acitivity_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:layout_margin="20dp"
        android:gravity="center"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/resultNumberTextView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="BMI : "
            android:textColor="@color/custom_black"
            android:textStyle="bold"
            android:textSize="20sp" />

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

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="20dp"
        android:gravity="center"
        android:orientation="horizontal">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="결과는 "
            android:textColor="@color/custom_black"
            android:textStyle="bold"
            android:textSize="20sp" />

        <TextView
            android:id="@+id/resultStringTextView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text=""
            android:textColor="@color/custom_black"
            android:textSize="20sp"
            android:textStyle="bold"
            tools:text="과체중입니다." />

    </LinearLayout>

</LinearLayout>

strings.xml과 colors.xml에서 height, weight, custom_black name을 따로 추가하였다.