GDSC HUFS 4기/Kotlin Team #6

[6팀] 코틀린으로 분 단위 계산기 만들기

백거누 2022. 10. 31. 00:42

 

이 글은 유데미 강의 Android 12 및 Kotlin 개발 완전 정복을 참고하여 작성하였습니다.

작성자 : 백건우

개발환경은 Windows, Android Studio입니다.

 

  • java - MainActivity.kt : 앱의 main kotlin 파일
  • res - layout - activity_main.xml : layout에 대한 xml 파일
  • res - values - colors.xml, strings.xml 등 : 각 값에 대한 xml 파일
    • colors.xml에 자주 사용하는 색을 변수로 설정할 수 있다.

1. 분 단위 나이 계산기(activity_main.xml 및 xml 파일들) - UI

  • xml 파일에 코드를 직접 작성하거나 디자인 탭에서 attributes를 설정할 수 있다.

LinearLayout

  • layout 클래스에 하위 뷰들을 배치하여 UI를 구성한다.
  • 속성
    • android:layout_width, layout_height
      • match_parent : content의 크기에 맞춰서 크기를 설정
      • wrap_content : 상속받은 클래스의 길이에 맞춤(단, 부모 클래스가 사용하고 남은 공간보다 자식 클래스의 내용이 길면 새로운 줄에 전체를 사용한다.)
    • android:orientation - 하위 뷰들의 배치 방식을 정한다.(수직, 수평 등)
    • android:background - layout의 배경색을 정한다.
    • android:gravity - 하위 뷰들의 정렬 방식을 정한다.
    • android:padding - 하위 뷰들의 둘레 여백의 크기를 설정한다.

TextView : 텍스트를 포함하는 뷰

Button : 클릭 가능한 버튼을 구현하는 이벤트 발생용 뷰

  • TextView, Button 등 layout의 하위 뷰들은 layout의 속성들을 상속받으며, 해당 속성들은 override가 가능하다.
  • 상속받은 속성 외에도 id, text, textColor, textStyle 등의 속성을 가지고 있다.
    • id - view에 접근할 때 id로 접근(findViewById 사용)
    • text, textColor, textStyle - 텍스트, 텍스트 색, 텍스트 스타일
    • margin - content를 제외한 공백을 설정
<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"
    tools:context=".MainActivity"
    android:orientation="vertical"
    android:background="@color/bgColor"
    android:gravity="center_horizontal"
    android:padding="16dp"
    >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="CALCULATE YOUR"
        android:textColor="@color/textBlue"
        android:textSize="25sp"
        android:textStyle="bold"
        />

    <Button
        android:id="@+id/btnDatePicker"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="SELECT DATE"
        android:backgroundTint="@color/btnBgColor"
        android:textColor="@color/lightGray"
        android:textStyle="bold"
        />
        
</LinearLayout>

크기 관련 단위

  • px : 절대적인 pixel 단위
  • dp : 화면에서의 비율, 화면의 크기가 달라져도 크기가 같다.
  • sp : 화면에서의 비율, 화면의 크기에 비례해 크기가 변한다.

2. 분 단위 나이 계산기(MainActivity.kt) - 기능 구현

DatePickerDialog : 달력에서 날짜를 고르는 클래스

버튼 클릭 시 OnDateSetListenerselectedYear, selectedMonth, selectedDayOfMonth에 달력에서 고른 year, month, dayofmonth를 입력받은 후 SimpleDateFormat(데이터를 입력받은 형식에 맞게 parsing해주는 클래스)와 System.currentTimeMillis()를 사용하여 1970년 1월 1일부터 선택된날짜, 현재까지의 날짜 까지 흐른 시간의 차이로 분 단위 나이를 구하여 TextView.text에 저장한다.

let : let{}를 사용하여 nullable 변수에 null이 아닐 때만 {}안의 내용을 실행하여 할당할 수 있게 하는 함수
(nullable 변수에 null이 들어갔을 때 발생할 수 있는 에러를 방지할 수 있다.)

import android.app.DatePickerDialog
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.TextView
import android.widget.Toast
import java.text.SimpleDateFormat
import java.util.*

class MainActivity : AppCompatActivity() {

    private var tvSelectedDate : TextView? = null
    private var tvAgeInMinutes : TextView? = null

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

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

        tvSelectedDate = findViewById(R.id.tvSelectedDate)
        tvAgeInMinutes = findViewById(R.id.tvAgeInMinutes)

        btnDatePicker.setOnClickListener {
            clickDatePicker()

        }
    }

    private fun clickDatePicker(){

        val myCalendar = Calendar.getInstance()
        val year = myCalendar.get(Calendar.YEAR)
        val month = myCalendar.get(Calendar.MONTH)
        val day = myCalendar.get(Calendar.DAY_OF_MONTH)
        val dpd = DatePickerDialog(this,
            // DatePickerDialog.OnDateSetListener는 DatePickerDialog가 예상가능한 부분이므로 생략 가능
            DatePickerDialog.OnDateSetListener{ _, selectedYear, selectedMonth, selectedDayOfMonth ->
                Toast.makeText(this,
                    "Year was $selectedYear, month was ${selectedMonth+1}" +
                            ", day of month was $selectedDayOfMonth",
                    Toast.LENGTH_LONG).show()

                val selectedDate = "$selectedYear/${selectedMonth+1}/$selectedDayOfMonth"

                tvSelectedDate?.text = selectedDate

                val sdf = SimpleDateFormat("yyyy/MM/dd", Locale.KOREAN)


                val theDate = sdf.parse(selectedDate)
                theDate?.let{
                    val selectedDateInMinutes = theDate.time / 60000

                    val currentDate = sdf.parse(sdf.format(System.currentTimeMillis()))
                    currentDate?.let{
                        val currentDateInMinutes = currentDate.time / 60000

                        val differenceInMinutes = currentDateInMinutes - selectedDateInMinutes

                        tvAgeInMinutes?.text = differenceInMinutes.toString()
                    }
                }
            },
            year,
            month,
            day
        )

        dpd.datePicker.maxDate = System.currentTimeMillis() - 86400000
        dpd.show()

    }

}