이 글은 유데미 강의 Android 12 및 Kotlin 개발 완전 정복을 참고하여 작성하였습니다.
작성자 : 유희수
개발환경은 Windows, Android Studio입니다.
이번 글에서 다룰 것 : 분 단위 계산기를 만드는 전 과정
# 전체적인 폴더 구조
● res/layout/activity_main.xml : 앱의 레이아웃 즉, 화면의 배치를 전담하는 파일 (버튼, 이미지, 텍스트 입력창 등)
▷레이아웃 xml로 화면 구성 : 화면을 구성하는데 필요한 요소들을 xml의 태그로 명시해 화면 구성하는 방법
▷ 디자인탭으로 화면 구성 : 위 사진의 오른쪽처럼 직접 요소를 끌어서 배치하는 방법
● java/com/example/dobcalc/MainActivity.kt : xml에 배치된 요소들에 기능을 구현하는 부분
1. 앱 기초 UI 구성하기
# LinearLayout
: 레이아웃 클래스에 다른 뷰를 포함해 화면 구성
: LinearLayout은 안드로이드 화면 구성을 x축이나 y축 방향으로 나열할 때 사용
- android:gravity="center_horizontal" : 하위 뷰들에 대한 배치 방향을 x축 중앙 정렬되게
- android:orientation="vertical" : 하위 뷰들을 수직 방향으로 배치
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
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 ... />
<Button ... />
<TextView ... />
</LinearLayout>
# TextView : 문자열을 출력하는 뷰
(디자인 탭에서) textview 클릭후 attributes에서 id, text, color 등 여러가지 속성 설정 가능
# Button : 이벤트 처리를 위한 클릭 기능이 포함되어 있는 뷰
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="IN MINIUTES"
android:textColor="#264653"
android:textSize="25sp"
android:textStyle="bold"
android:layout_marginTop="16dp" />
<Button
android:text="SELECT DATE"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/btnDatePicker"
android:textColor="@color/lightgray"
android:backgroundTint="@color/btnBgColor"/>
- layout_width, layout_height
- wrap_content : 포함된 내용(글자 or 이미지크기)을 보여줄 수 있는 크기로 설정
- match_parent : 부모 뷰의 길이에 맞춤
- Button의 경우 가로가 match_parent 라서 화면 전체 넓이에 맞춰서 버튼 크기가 지정됨
- id
- id를 설정해서 기능 구현할때 view에 접근해야할 때 id로 보통 접근
- XML 파일에서 : android:id = "@+id/button_name"
- Kt 파일에서 : 위젯 변수 = (위젯 명) findViewById(R.id.위젯_id);
- textColor, backgroundColor ..
- 직접 color 원하는대로 설정 가능
- 자주 쓰는 색깔의 경우 res/values/colors.xml 파일에 저장해서 사용
- <color name="lightgray">#b7b7a4</color>
- padding, margin
- dp, sp, px
- px : 전체 화면의 크기와 상관없이 지정한 pixel만큼 표시되는 절대적 표시 단위이다.
- dp : 다양한 기기에서 UI 요소의 실제 크기에 일관성을 부여
- sp : dp 단위와 같지만, 사용자의 글꼴 크기 환경설정에 의해 확장되기도 합니다
- res/values/strings.xml : app_name 수정 가능
2. MainActivity.kt에서 기능 구현
# DatePickerDialog : 달력 dialog 생성
- 2번째 파라미터로 OnDateSetListener로 달력에서 날짜를 선택했을 시 동작을 선언해주며 '년/월/일'을 '${selectedYear}/${selectedMonth+1}/${selectedDayOfMonth}'로 읽을 수 있다.
- 이때 월을 나타내는 m은 0~11까지의 수를 갖기 때문에 +1을 해줘야 월을 제대로 얻을 수 있다
- 3~5번째 파라미터로 준 year, month, day는 달력 호출 시 디폴트로 선택되어 있는 날짜를 지정하며 밑에 코드처럼 Calendar 인스턴스를 생성해 현재 날짜를 디폴트 값으로 주게 했다
val myCalender = Calendar.getInstance() // 캘린더 인스턴스 생성
val year = myCalender.get(Calendar.YEAR) // 현재 날짜 가져오기
val month = myCalender.get(Calendar.MONTH)
val day = myCalender.get(Calendar.DAY_OF_MONTH)
val dpd = DatePickerDialog(this,
DatePickerDialog.OnDateSetListener{ view, selectedYear, selectedMonth, selectedDayOfMonth ->
...
},
year,
month,
day
)
# 버튼 클릭시 Toast 메세지 띄우기
Toast.makeText(this,
"btnDataPicker pressed", Toast.LENGTH_LONG).show() // 나타낼 문자와 얼마나 길게 메세지를 보여줄 것인지
class MainActivity : AppCompatActivity() {
var tvSelectedDate : TextView? = null
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()
}
}
fun clickDatePicker(){
val myCalender = Calendar.getInstance()
val year = myCalender.get(Calendar.YEAR)
val month = myCalender.get(Calendar.MONTH)
val day = myCalender.get(Calendar.DAY_OF_MONTH)
val dpd = DatePickerDialog(this,
DatePickerDialog.OnDateSetListener{ view, selectedYear, selectedMonth, selectedDayOfMonth ->
Toast.makeText(this,
"btnDataPicker pressed", Toast.LENGTH_LONG).show()
val selectedDate = "${selectedYear}/${selectedMonth+1}/${selectedDayOfMonth}"
//tvSelectedDate?.setText(selectedDate)
tvSelectedDate?.text = selectedDate // view 요소에 선택된 날짜를 보여줄 수 있도록 text 변경
val sdf = SimpleDateFormat("yyyy/MM/dd", Locale.KOREAN) // 원하는 날짜 형식 포맷 작성
val theDate = sdf.parse(selectedDate) // string -> (SimpleDateFormat) -> Date 형식으로 변경
theDate?.let { // 이렇게하면 날짜 선택 여부를 확인하고 날짜가 선택됐을때만 실행됨
// millisecond 기준이기 때문에 분 단위를 구하려면 1000(1초)*60 -> 1분
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 // 86400000 : 1일
dpd.show()
}
}
'GDSC HUFS 4기 > Kotlin Team #2' 카테고리의 다른 글
[2팀] 퀴즈 앱 만들기(2) (0) | 2022.11.08 |
---|---|
[2팀] 코틀린으로 XML, UI를 생성해서 계산기 만들기 (0) | 2022.10.31 |
[2팀] 객체지향 프로그래밍 기초(2) (1) | 2022.10.13 |
[2팀] 코틀린 객체지향 프로그래밍 기초 (1) (1) | 2022.10.05 |
[2팀] 코틀린 기초 더 배우기(2) (0) | 2022.10.05 |