안드로이드 공식 문서, Android Basics in Kotlin 과정을 학습하며 기록하고 및 요약하기 위한 글입니다.
"[학습] Android Basics in Kotlin 과정 소개" > Unit 1: Kotlin 기초 > "App에 버튼 생성" 중 다음 내용을 요약했습니다.
- Kotlin의 Classe, object instance (원문, 원문 최종 업데이트일: 2021.07.10)
- 대화형 Dice Roller App 만들기 (원문, 원문 최종 업데이트일: 2021.03.30)
- Kotlin에 조건부 동작 추가 (원문, 원문 최종 업데이트일: 2022.04.09)
- Dice Roller App에 이미지 추가 (원문, 원문 최종 업데이트일: 2021.11.24)
학습일: 2023.01.06 ~ 01.09
- 앱 소개: 주사위를 굴려 랜덤한 결과를 얻는 앱
- 사용 요소: ConstraintLayout, Button, ImageView
- 주요 학습 내용
- Class를 정의하고, 해당 Class의 객체를 생성하고 사용
- 조건문(when) 사용
- IntRange 데이터 타입과, random() 함수 사용
- 이미지 리소스 추가 및 이미지 업데이트
- 버튼에 클릭 이벤트 추가
- 앱 화면
새 프로젝트 만들기
----------------------------------------------------------------------------------------------
- Empty Activity 템플릿 선택
- Name : Dice Roller
- Language: Kotlin
- Minumum SDK : API 19: Android 4.4 (KitKat)
----------------------------------------------------------------------------------------------
앱 레이아웃 만들기
필요한 View
요소는 아래와 같습니다.
- 주사위 모양
ImageView
- [굴리기]
Button
문자열 리소스 추가 및 변경
app/res/values/strings.xml
<resources>
<string name="app_name">주사위 굴리기</string>
<string name="roll">굴리기</string>
</resources>
이미지(drawable) 리소스 추가
1. 이미지 다운로드 URL을 열어 6개의 주사위 이미지가 있는 ZIP 파일을 다운로드 후 압축을 해제합니다.
2. View > Tool Windows > Resource Manager (또는 안드로이드 스튜디오 왼쪽 Resource Manager 탭 클릭)
3. Resource Manager 창에서 + 를 클릭하고, Import Drawables을 선택합니다.
4. Import할 이미지(위에서 다운로드 받은 이미지 6개)를 선택하여 Import 합니다.
5. Resource Manager(app>res>drawable)에 6개의 이미지가 표시됩니다.
위 이미지들은 Kotlin 코드에서 Resource ID로 참조 가능합니다.
(R.drawable.dice_1
~ R.drawable.dice_6
)
최종 레이아웃 코드
Design 탭에서 레이아웃을 배치하는 방법은 원문을 통해 확인하실 수 있습니다.
저는 해당 속성들의 최종 Code를 공유하는 것으로 대신하겠습니다.
app > res> layout > activity_main.xml
파일
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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">
<!-- [주사위 이미지] ImageView 속성 설정 -->
<ImageView
android:id="@+id/imageView"
android:layout_width="160dp"
android:layout_height="200dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:srcCompat="@drawable/dice_1" />
<!-- [굴리기] Button 속성 설정 -->
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/roll"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/imageView" />
</androidx.constraintlayout.widget.ConstraintLayout>
tools:srcCompat 속성에 대한 참고 사항
- ImageView
의 경우 Design > Attributes에는 두 개의 srcCompat 속성이 있습니다. 그중 하나에는 도구 아이콘이 있습니다.
- 도구 아이콘이 있는 srcCompat 속성은 Design 탭에서만 미리보기(위치 배치하는) 용도로 표시되는 것이며, 실제로 에뮬레이터나 기기에서 앱을 실행할 때는 표시되지 않습니다.
(도구 아이콘이 없는 srcCompat 속성의 경우 미리 보기는 물론 앱 실행시에도 표시됩니다.)
- 도구 아이콘이 없는 srcCompat 설정은 Code 상에서는 app:srcCompat="@drawable/dice_1" 로 설정됩니다.
- 도구 아이콘이 있는 srcCompat 설정은 Code 상에서는 tools:srcCompat="@drawable/dice_1"로 설정됩니다.
- 추가로 TextView
의 text의 경우도 실제 표시되는 text와 미리보기 용도의 도구 아이콘이 있는 text가 있습니다.
- Code 상에서도 android:text, tools:text 로 각각 설정됩니다.
- 도구 아이콘이 있는 text의 경우 앱 개발자에게만 보이는 화면으로 문자열 리소스로 추출할 필요가 없습니다.
앱 기능 구현
MainActivity.kt
파일을 엽니다. (app > java > com.example.diceroller > MainActivity.kt)
최종 코드 및 주석
package com.example.diceroller
import android.os.Bundle
import android.widget.Button
import android.widget.ImageView
import androidx.appcompat.app.AppCompatActivity
/**
* 이 Activity는 사용자가 주사위를 굴리고 결과를 화면에 표시합니다.
*/
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// [굴리기] 버튼에 클릭 이벤트 설정
// 1. 버튼 참조 가져오기
var rollButton: Button = findViewById(R.id.button)
// 2. 버튼에 클릭 이벤트 리스너 설정
rollButton.setOnClickListener { rollDice() }
// 앱이 시작될 때 주사위 굴리기
// 이 부분은 없어도 되지만, 첫 실행 화면에 어떤 앱인지 보여주기 위해서 최소 실행시도 주사위 굴리기를 실행하도록 함
rollDice()
}
/**
* 주사위를 굴리고 결과를 화면에 업데이트합니다.
*/
private fun rollDice() {
// 6면인 주사위(Dice) 객체를 생성하고 굴립니다.
val dice = Dice(6) // 1. 주사위 객체 생성
val diceRoll = dice.roll() // 2. 주사위 굴리기
// --------------------------------------------------
// 주사위를 굴린 결과를 화면에 업데이트합니다.
// 1. ImageView 참조 가져오기
val diceImage: ImageView = findViewById(R.id.imageView)
// 2. 주사위 굴린 결과에 따른 리소스 설정
val drawableResource = when(diceRoll){
1-> R.drawable.dice_1
2-> R.drawable.dice_2
3-> R.drawable.dice_3
4-> R.drawable.dice_4
5-> R.drawable.dice_5
else-> R.drawable.dice_6
}
// 3. ImageView 이미지 업데이트
diceImage.setImageResource(drawableResource)
// 4. 스크린 리더가 읽을 수 있더록 이미지에 대한 설명을 추가
diceImage.contentDescription = diceRoll.toString()
}
}
/**
* 고정된 면을 갖는 주사위(Dice) Class
*/
class Dice(private val numSides: Int) {
/**
* 주사위를 굴리고 랜덤 결과를 반환
*/
fun roll(): Int {
return (1..numSides).random()
}
}
코드 간략 설명
MainActivity에는 main() 함수가 없습니다.
앞서 모든 Kotlin 프로그램에는 main()
함수가 있어야 한다고 했습니다. Android 앱은 다르게 작동합니다.
main()
함수를 호출하는 대신 Android 시스템은 앱이 처음 열릴 때 MainActivity
의 onCreate()
메서드를 호출합니다.
[굴리기] 버튼에 클릭 이벤트 설정
// 1. 버튼 참조 가져오기
: findViewById(R.id.버튼ID)
// 2. 버튼에 클릭 이벤트 리스너 설정
: 버튼변수.setOnClickListener { 클릭시 작업할 내용 }
참고. setContentView
호출 이후에 findViewById
를 사용해야 합니다. 그렇지 않은 경우 NullPointerException이 발생합니다.
고정된 면을 갖는 주사위(Dice) Class 정의
- class 클래스명(인수) { }: Class 정의
class
키워드를 사용, 클래스명은 대문자 카멜 표기법(예:Dice, Car, CustomerRecord)
예: class Dice { }
, class Dice(private val numSides: Int) { }
- (시작수..끝수): IntRange
데이터 타입으로, 시작수 부터 끝수까지 정수의 범위를 나타냅니다.
예: val range = 1..6
- (시작수..끝수).random(): Kotlin에 내장된 random()
함수를 사용하여, 주어진 범위의 랜덤 숫자를 생성하고 반환합니다.
예: (100..200).random()
, (1..numSides).random()
ImageView 이미지 업데이트
// 1. ImageView 참조 가져오기
: findViewById(R.id.ImageView의ID)
// 3. ImageView 이미지 업데이트
: 이미지참조변수.setImageResource(리소스)
// 4. 스크린 리더가 읽을 수 있더록 이미지에 대한 설명을 추가
: 이미지참조변수.contentDescription = "이미지에 대한 설명"
조건문: if, else if, else 사용 예
val num = 4
if (num > 4) {
println("The variable is greater than 4")
} else if (num == 4) {
println("The variable is equal to 4")
} else {
println("The variable is less than 4")
}
조건문: when 사용 예
val drawableResource = when(diceRoll){
1-> R.drawable.dice_1
2-> R.drawable.dice_2
3-> R.drawable.dice_3
4-> R.drawable.dice_4
5-> R.drawable.dice_5
else-> R.drawable.dice_6
}
참고: 변수에 할당할 경우, else->
식이 추가되어야 조건에 맞지 않는 경우까지 완전하게 할당할 수 있습니다.
추가 설명
Activity
- 앱이 UI를 그리는 창을 제공합니다.
- 일반적으로 Activity는 실행되는 앱의 전체 화면을 차지합니다.
- 모든 앱에는 하나 이상의 Activity가 있습니다.
- 앱은 기본적으로 MainActivity에서 시작됩니다. (시작 Activity 설정은 변경 가능합니다.)
- 이번 실습인 "주사위 굴리기 앱"에서는 주사위를 굴리는 Button과 결과를 표시하는 Activity가 하나 있습니다.
끝까지 읽어 주셔서 감사합니다. ^^
'냐냐한 Dev Study > Android' 카테고리의 다른 글
[학습] 레모네이드 앱 프로젝트 (Android,Kotlin) (4) | 2023.01.10 |
---|---|
[학습] 생일 축하 메세지 표시하는 간단 Android 앱 만들기 (Kotlin) (0) | 2023.01.06 |
[학습] Kotlin으로 Hello World + 생일 축하 메세지 작성 (0) | 2023.01.05 |
[학습] Android Basics in Kotlin 과정 소개 (0) | 2023.01.04 |
안드로이드 간단 시계(날짜/시간) 만들기 (Java) (0) | 2022.12.27 |