대화형 Dice Roller 앱 만들기

1. 시작하기 전에

이 Codelab에서는 사용자가 앱에서 Button을 클릭하여 주사위를 굴리는 Dice Roller Android 앱을 만듭니다. 주사위 굴리기의 결과는 화면의 TextView에 표시됩니다.

Android 스튜디오에서 Layout Editor를 사용하여 앱 레이아웃을 빌드하고, Button을 클릭할 때 발생하는 결과에 관한 Kotlin 코드를 작성합니다.

기본 요건

  • Android 스튜디오에서 'Hello, World!' 앱을 만들고 실행하는 방법 이해
  • 앱에서 TextViews를 사용하는 방법 이해
  • Layout Editor에서 TextView의 속성을 수정하는 방법 이해
  • 문자열 리소스로 텍스트를 추출하여 더 쉽게 앱을 번역하고 문자열을 재사용하는 방법 이해
  • Kotlin 프로그래밍 기초 이해

학습할 내용

  • Android 앱에 Button을 추가하는 방법
  • 앱에서 Button을 탭할 때 동작을 추가하는 방법
  • 앱의 Activity 코드를 열고 수정하는 방법
  • Toast 메시지를 표시하는 방법
  • 앱이 실행되는 동안 TextView의 콘텐츠를 업데이트하는 방법

빌드할 프로그램

  • 주사위를 굴리는 Button이 있고 주사위 굴리기 결과로 화면의 텍스트를 업데이트하는 Dice Roller Android 앱

요구사항

  • Android 스튜디오가 설치된 컴퓨터

이 Codelab을 완료하면 앱은 다음과 같이 표시됩니다.

2e8416293e597725.png

2. 앱 설정

Empty Activity 프로젝트 만들기

  1. Android 스튜디오에서 이미 기존 프로젝트가 열려 있다면 File > New > New Project...로 이동하여 Create New Project 화면을 엽니다.
  2. Create New Project에서 Empty Activity 템플릿을 사용하여 새 Kotlin 프로젝트를 만듭니다.
  3. 최소 API 수준 19(KitKat)로 'Dice Roller' 앱을 호출합니다.

cd369d7a6bb01f97.png

  1. 새 앱을 실행하면 다음과 같이 표시됩니다.

d9a6470c99790ef5.png

3. 앱 레이아웃 만들기

Layout Editor 열기

  1. Project 창에서 activity_main.xml(app > res > layout > activity_main.xml)을 더블클릭하여 엽니다. Layout Editor가 표시되고 앱 중앙에 'Hello World' TextView만 있습니다. f737b63b4f821f32.png

다음으로 앱에 Button을 추가합니다. Button은 사용자가 탭하여 작업을 실행할 수 있는 Android의 사용자 인터페이스(UI) 요소입니다.

5efd52b1ba8dd391.png

이 작업에서는 'Hello World' TextView 아래에 Button을 추가합니다. TextViewButtonViewGroup 유형인 ConstraintLayout 내에 있습니다.

ViewGroup 내에 Views가 있으면 Views상위 ViewGroup하위 요소로 간주됩니다. 개발자 앱의 경우 TextViewButton이 상위 ConstraintLayout의 하위 요소로 간주됩니다.

624aeb04dbe9909d.png ea4be68b34500570.png

앱에서 기존 ConstraintLayout의 하위 요소로 Button을 추가합니다.

레이아웃에 Button 추가

  1. Palette에서 Design 뷰로 Button을 드래그하여 'Hello World' TextView 아래에 배치합니다.

b57f8297ec57f005.png

  1. Component TreePalette 아래에서 ButtonTextViewConstraintLayout 아래에(ConstraintLayout의 하위 요소로) 나열되어 있는지 확인합니다.
  2. Button이 제한되지 않는다는 오류가 표시됩니다. ButtonConstraintLayout 내에 있으므로 세로 및 가로 제약 조건을 설정하여 배치해야 합니다.

b875e0147bf9e3f5.png

Button 배치

이 단계에서는 Button 상단의 세로 제약 조건을 TextView 하단에 추가합니다. 이렇게 하면 TextView 아래에 Button이 배치됩니다.

  1. Design 뷰에서 Button 상단 가장자리의 테두리가 파란색인 흰색 원을 길게 누릅니다. 포인터를 드래그하면 화살표가 포인터를 따라갑니다. 'Hello World' TextView의 하단 가장자리에 도달하면 놓습니다. 이렇게 하면 레이아웃 제약 조건이 설정되고 ButtonTextView 바로 아래까지 위로 슬라이드됩니다.

a1973a29e117dd8f.gif

  1. Layout Editor 오른쪽에 있는 Attributes를 확인합니다.
  2. Constraint Widget에서 TextView 하단, Top → BottomOf textView (0dp)로 설정된 새 레이아웃 제약 조건을 확인합니다. (0dp)는 여백이 0임을 나타냅니다. 가로 제약 조건 누락이라는 오류도 있습니다.

88b750fbe0504d93.png

  1. Button 왼쪽의 가로 제약 조건을 상위 ConstraintLayout 왼쪽에 추가합니다.
  2. 오른쪽에도 반복하여 Button 오른쪽 가장자리를 ConstraintLayout 오른쪽 가장자리에 연결합니다. 다음과 같은 결과가 표시됩니다.

49de1c166b355ee1.png

  1. 여전히 Button이 선택된 상태에서 Constraint Widget은 다음과 같이 표시됩니다. 추가된 제약 조건 두 가지는 Start → StartOf parent (0dp), End → EndOf parent (0dp)입니다. 즉, Button이 상위 요소인 ConstraintLayout에서 가로로 가운데 위치합니다.

dd1bac8adb275f79.png

  1. 앱을 실행하면 아래 스크린샷과 같이 표시됩니다. Button을 클릭할 수 있지만 아무것도 실행되지 않습니다. 계속 진행하겠습니다.

fbe13b0b8bf60aff.png

Button 텍스트 변경

Layout Editor에서 UI를 몇 가지 더 변경합니다.

Button 라벨이 'Button'을 표시하도록 하는 대신 버튼이 할 작업을 나타내는 'Roll'로 변경합니다.

  1. Layout Editor에서 Button이 선택된 상태로 Attributes로 이동하여 textRoll로 변경하고 Enter(Mac은 Return) 키를 누릅니다.

9adeab9db109913e.png

  1. Component Tree에서 주황색 경고 삼각형이 Button 옆에 표시됩니다. 삼각형 위로 포인터를 가져가면 메시지가 표시됩니다. Android 스튜디오는 앱 코드에서 하드코딩 문자열('Roll')을 감지하고 대신 문자열 리소스를 사용하라고 제안합니다.

하드코딩 문자열이 있으면 앱을 다른 언어로 번역하기 더 어렵고 문자열을 앱의 다른 부분에서 재사용하기도 더 어렵습니다. 다행히 Android 스튜디오에는 자동 수정 기능이 있습니다.

6e9a5a173a49fc8b.png

  1. Component Tree에서 주황색 삼각형을 클릭합니다.

e4f601421031a5f3.png

전체 경고 메시지가 열립니다.

7206a03c9ba0d68d.png

  1. 메시지 하단의 Suggested Fix아래 Fix 버튼을 클릭합니다. (아래로 스크롤해야 할 수 있음)
  2. Extract Resource 대화상자가 열립니다. 문자열을 추출한다는 것은 'Roll' 텍스트를 가져와 strings.xml(app > res > values > strings.xml)에서 roll이라는 문자열 리소스를 만든다는 의미입니다. 기본값이 올바르므로 OK를 클릭합니다.

78dc6e6f7abc1152.png

  1. Attributes에서 Buttontext 속성은 이제 @string/roll로 표시되어 방금 만든 리소스를 나타냅니다.

4fa3d5e4bce95d2.png

Design 뷰에서 Button은 여전히 Roll로 표시됩니다.

5bdd2399b9664fca.png

TextView 스타일 지정

'Hello World!' 텍스트는 상당히 작고 메시지가 앱과 관련이 없습니다. 이 단계에서는 작은 'Hello, World!' 메시지를 주사위를 굴린 값을 나타내는 숫자로 바꾸고 글꼴을 키워 더 보기 쉽게 합니다.

  1. Design Editor에서 TextView를 선택하여 속성이 Attributes 창에 표시되도록 합니다.
  2. TextViewtextSize36sp로 변경하여 크고 읽기 쉽게 만듭니다. 스크롤하여 textSize를 찾아야 할 수 있습니다.

ca5dbfd4f37a49e7.png

  1. TextViewtext 속성을 삭제합니다. 사용자가 주사위를 굴릴 때까지 TextView에 어떤 것도 표시하지 않아도 됩니다.

da4031d0ef02f3c5.png

그러나 앱의 레이아웃과 코드를 수정할 때 TextView에 텍스트를 표시하면 매우 유용합니다. 이를 위해 TextView에 레이아웃 미리보기에만 표시되고 앱이 실행 중일 때는 표시되지 않는 텍스트를 추가할 수 있습니다.

  1. Component Tree에서 TextView를 선택합니다.
  2. Common Attributes 아래에서 text 속성을 찾고 그 아래에서 도구 아이콘이 있는 다른 text 속성을 찾습니다. text 속성은 앱이 실행 중일 때 사용자에게 표시되는 내용입니다. 도구 아이콘이 있는 text 속성은 개발자만을 위한 '도구 텍스트' 속성입니다.
  3. TextView에서 도구 텍스트를 '1'로 설정합니다(주사위 굴리기 값 1이 있다고 가정함). '1'은 Android 스튜디오 내 Design Editor에만 표시되고 실제 기기 또는 에뮬레이터에서 앱을 실행할 때는 표시되지 않습니다.

eaf488ba04947f7f.png

이 텍스트는 앱 개발자만 볼 수 있으므로 텍스트의 문자열 리소스를 만들지 않아도 됩니다.

  1. 미리보기에서 앱을 확인합니다. '1'이 표시됩니다.

bbfbfec435beb0cd.png

  1. 앱을 실행합니다. 에뮬레이터에서 실행할 때 앱은 다음과 같이 표시됩니다. '1'이 표시되지 않습니다. 이는 올바른 동작입니다.

577368e5c11a4d6e.png

레이아웃 변경이 완료되었습니다.

앱에 버튼이 있지만 버튼을 탭해도 아무것도 실행되지 않습니다. 이를 변경하려면 주사위를 굴리고 버튼을 탭할 때 화면을 업데이트하는 Kotlin 코드를 작성해야 합니다.

이렇게 변경하려면 Android 앱이 구조화되는 방식을 자세히 알아야 합니다.

4. Activity 소개

Activity는 앱이 UI를 그리는 창을 제공합니다. 일반적으로 Activity는 실행되는 앱의 전체 화면을 차지합니다. 모든 앱에는 활동이 하나 이상 있습니다. 최상위 수준 또는 첫 번째 활동을 종종 MainActivity라고 하고 프로젝트 템플릿에서 제공합니다. 예를 들어 사용자가 기기에서 앱 목록을 스크롤하여 'Dice Roller' 앱 아이콘을 탭하면 Android 시스템은 앱의 MainActivity를 시작합니다.

MainActivity 코드에서 Activity의 레이아웃에 관한 세부정보와 사용자가 상호작용하는 방법을 제공해야 합니다.

  • Birthday Card 앱에는 생일 메시지와 이미지를 표시하는 Activity가 하나 있습니다.
  • Dice Roller 앱에는 방금 빌드한 TextViewButton 레이아웃을 표시하는 Activity가 하나 있습니다.

더 복잡한 앱의 경우 화면 여러 개와 Activity 두 개 이상이 있을 수 있습니다. 각 Activity에는 특정 목적이 있습니다.

예를 들어 사진 갤러리 앱에는 사진 그리드를 표시하는 Activity, 개별 사진을 보는 두 번째 Activity, 개별 사진을 편집하는 세 번째 Activity가 있을 수 있습니다.

97946b75b52c94b4.png

MainActivity.kt 파일 열기

코드를 추가하여 MainActivity의 버튼 탭에 응답합니다. 올바르게 이 작업을 실행하려면 앱에 이미 있는 MainActivity 코드에 관해 자세히 알아야 합니다.

  1. MainActivity.kt 파일(app > java > com.example.diceroller > MainActivity.kt)로 이동하여 파일을 엽니다. 다음과 같이 표시됩니다. import...가 표시되면 ...을 클릭하여 가져오기를 펼칩니다.
package com.example.diceroller

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle

class MainActivity : AppCompatActivity() {

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

위 코드를 완전하게 이해할 필요는 없지만 코드가 어떤 기능을 하는지 전반적으로 알아야 합니다. Android 코드를 더 많이 사용할수록 코드에 더 익숙해지고 이해도도 높아집니다.

  1. 키워드 class에 이어 이름으로 식별된 MainActivity 클래스의 Kotlin 코드를 확인합니다.
class MainActivity : AppCompatActivity() {
    ...
}
  1. MainActivity에는 main() 함수가 없습니다.

앞서 모든 Kotlin 프로그램에는 main() 함수가 있어야 한다고 알아봤습니다. Android 앱은 다르게 작동합니다. main() 함수를 호출하는 대신 Android 시스템은 앱이 처음 열릴 때 MainActivityonCreate() 메서드를 호출합니다.

  1. 아래 코드와 같은 onCreate() 메서드를 찾습니다.
   override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
       setContentView(R.layout.activity_main)
   }

이후 Codelab에서 override를 알아봅니다. 따라서 지금은 걱정하지 않아도 됩니다. onCreate() 메서드의 나머지는 가져오기의 코드를 사용하고 setContentView()로 시작 레이아웃을 설정하여 MainActivity를 설정합니다.

  1. import로 시작하는 줄을 확인합니다.

Android는 여러 클래스의 프레임워크를 제공하여 Android 앱 작성을 더 쉽게 하지만 어떤 클래스를 의미하는지 정확하게 알아야 합니다. import 문을 사용하여 코드에서 사용할 프레임워크의 클래스를 지정할 수 있습니다. 예를 들어 Button 클래스는 android.widget.Button에 정의되어 있습니다.

자동 가져오기 사용 설정

클래스를 더 많이 사용할 때 import 문 추가를 기억하는 것은 어려울 수 있습니다. 다행히 Android 스튜디오를 통해 다른 개발자가 제공한 클래스를 사용할 때 올바른 가져오기를 선택할 수 있습니다. 이 단계에서는 가능할 때 가져오기를 자동으로 추가하고 사용되지 않는 가져오기를 코드에서 자동으로 삭제하도록 Android 스튜디오를 구성합니다.

macOS에서는 File > New Project Settings > Preferences for New Project...(파일 > 새 프로젝트 설정 > 새 프로젝트 환경설정...)로 이동하여 설정을 엽니다. Other Settings > Auto Import(기타 설정 > 자동 가져오기)를 펼칩니다. JavaKotlin 섹션에서 Add unambiguous imports on the fly(즉시 명확한 가져오기 추가) 및 Optimize imports on the fly (for current project)(즉시 가져오기 최적화(현재 프로젝트))가 선택되어 있는지 확인합니다. 각 섹션에는 체크박스가 두 개 있습니다. 변경사항을 저장하고 OK(확인)를 눌러 설정을 닫습니다.

1bedf6b103fd48c3.png

Windows에서는 File > Settings > Editor > General > Auto Import(파일 > 설정 > 편집기 > 일반 > 자동 가져오기)로 이동하여 설정을 엽니다. JavaKotlin 섹션에서 Add unambiguous imports on the fly(즉시 명확한 가져오기 추가) 및 Optimize imports on the fly (for current project)(즉시 가져오기 최적화(현재 프로젝트))가 선택되어 있는지 확인합니다. 각 섹션에는 체크박스가 두 개 있습니다. 변경사항을 저장하고 OK(확인)를 눌러 설정을 닫습니다.

f1e7ad59d220294e.png

unambiguous imports 설정은 Android 스튜디오가 사용할 문을 결정할 수 있는 한 import 문을 자동으로 추가하라고 Android 스튜디오에 지시합니다. optimize imports 설정은 Android 스튜디오에 코드에서 사용되지 않는 가져오기를 삭제하라고 지시합니다.

5. Button을 대화형으로 만들기

이제 MainActivity에 관해 좀 더 알아봤으므로 앱을 수정하여 Button을 클릭하면 화면에서 무언가가 실행되도록 합니다.

Button을 클릭할 때 메시지 표시

이 단계에서는 버튼을 클릭할 때 간단한 메시지가 화면 하단에 표시되도록 지정합니다.

b6f4b2fa7f7434a4.png

  1. setContentView() 호출 후 onCreate() 메서드에 다음 코드를 추가합니다. findViewById() 메서드는 레이아웃에서 Button을 찾습니다. R.id.buttonButton의 리소스 ID로, Button의 고유한 식별자입니다.
val rollButton: Button = findViewById(R.id.button)

이 코드는 Button 객체 자체가 아니라 rollButton이라는 변수에 Button 객체 참조를 저장합니다.

이제 onCreate() 메서드가 다음과 같이 표시됩니다.

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

   val rollButton: Button = findViewById(R.id.button)
}
  1. Android 스튜디오가 Buttonimport 문을 자동으로 추가했는지 확인합니다. 이제 import 문이 3개 있습니다.
import android.os.Bundle
import android.widget.Button
import androidx.appcompat.app.AppCompatActivity

그런 다음 Button을 탭할 때 코드가 실행될 수 있도록 코드를 Button과 연결해야 합니다. 클릭 리스너는 탭 또는 클릭이 발생할 때 실행할 작업을 위한 코드입니다. 사용자가 클릭하는 것을 '수신 대기'하는, 이 경우에는 Button에 있는 코드로 생각하면 됩니다.

  1. rollButton 객체를 사용하고 setOnClickListener() 메서드를 호출하여 클릭 리스너를 설정합니다. 메서드 이름 뒤에 괄호가 아니라 실제로 메서드 이름 뒤에 중괄호를 사용합니다. 이는 람다를 선언하는 특수 구문으로, 향후 Codelab에서 자세히 알아봅니다.

지금 알아야 할 내용은 버튼을 탭할 때 발생해야 하는 작업에 관한 명령을 중괄호 안에 입력하는 것입니다. 다음 단계에서는 간략한 메시지인 토스트 메시지를 앱에서 표시합니다.

rollButton.setOnClickListener {
}

입력할 때 Android 스튜디오에 여러 가지 제안이 표시될 수 있습니다. 이 경우 setOnClickListener {...} 옵션을 선택합니다.

a3d45c0348b109d2.png

버튼을 탭할 때 발생해야 하는 작업에 관한 명령을 중괄호 안에 입력합니다. 지금은 사용자에게 표시되는 간략한 메시지인 Toast를 앱에서 표시합니다.

  1. Toast.makeText()를 호출하여 "Dice Rolled!" 텍스트로 Toast를 만듭니다.
val toast = Toast.makeText(this, "Dice Rolled!", Toast.LENGTH_SHORT)
  1. 그런 다음 show() 메서드를 호출하여 Toast에 자체를 표시하라고 지시합니다.
toast.show()

업데이트된 MainActivity 클래스는 다음과 같습니다. packageimport 문이 여전히 파일 상단에 있습니다.

class MainActivity : AppCompatActivity() {

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

       val rollButton: Button = findViewById(R.id.button)
       rollButton.setOnClickListener {
           val toast = Toast.makeText(this, "Dice Rolled!", Toast.LENGTH_SHORT)
           toast.show()
       }
   }
}

변수 없이 클릭 리스너의 두 줄을 한 줄로 결합할 수 있습니다. 다음은 다른 코드에서 흔히 볼 수 있는 패턴입니다.

Toast.makeText(this, "Dice Rolled!", Toast.LENGTH_SHORT).show()
  1. 앱을 실행하고 Roll 버튼을 클릭합니다. 토스트 메시지가 화면 하단에 잠시 표시되었다가 사라집니다.

fe4a03053b25cb7a.png

잘했습니다. 버튼을 클릭하면 메시지가 표시됩니다. 처음으로 Android용 Kotlin 코드를 작성했습니다.

Button을 클릭할 때 TextView 업데이트

임시 Toast 메시지를 표시하는 대신 Roll 버튼을 클릭할 때 화면의 TextView를 업데이트하는 코드를 작성합니다.

  1. activity_main.xml(app > res > layout > activity_main.xml)로 돌아갑니다.
  2. TextView를 클릭합니다.
  3. idtextView입니다.

dee0d8e4ef8ccf66.png

  1. MainActivity.kt(app > java > com.example.diceroller > MainActivity.kt)를 엽니다.
  2. Toast를 만들고 표시하는 코드 줄을 삭제합니다.
rollButton.setOnClickListener {

}
  1. 삭제된 코드 자리에서 resultTextView라는 새 변수를 만들어 TextView를 저장합니다.
  2. findViewById()를 사용하여 레이아웃에서 ID로 textView를 찾고 그 참조를 저장합니다.
val resultTextView: TextView = findViewById(R.id.textView)
  1. resultTextView의 텍스트를 따옴표로 묶인 6으로 설정합니다.
resultTextView.text = "6"

Attributes에서 text를 설정하여 실행한 작업과 비슷하지만 이제 코드에 있으므로 텍스트는 큰따옴표 안에 있어야 합니다. 이를 명시적으로 설정하면 현재는 TextView에 항상 6이 표시된다는 의미입니다. 다음 작업에서는 주사위를 굴려 다양한 값을 표시하는 코드를 추가합니다.

MainActivity 클래스는 다음과 같이 표시됩니다.

class MainActivity : AppCompatActivity() {

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

       val rollButton: Button = findViewById(R.id.button)
       rollButton.setOnClickListener {
           val resultTextView: TextView = findViewById(R.id.textView)
           resultTextView.text = "6"
       }
   }
}
  1. 앱을 실행하여 버튼을 클릭합니다. TextView가 '6'으로 업데이트됩니다.

40a78aac9e1b5b20.png

6. 주사위 굴리기 로직 추가

실제로 주사위를 굴리는 작업만 누락되어 있습니다. 주사위 굴리기 로직을 처리하는 이전 Codelab의 Dice 클래스를 재사용할 수 있습니다.

Dice 클래스 추가

  1. MainActivity 클래스의 마지막 중괄호 뒤에 roll() 메서드를 사용하여 Dice 클래스를 만듭니다.
class Dice(val numSides: Int) {

   fun roll(): Int {
       return (1..numSides).random()
   }
}
  1. Android 스튜디오에서 물결 모양의 회색 선으로 numSides에 밑줄을 그을 수 있습니다. 표시되는 데 시간이 걸릴 수 있습니다.
  2. numSides 위로 포인터를 가져가면 Property ‘numSides' could be private이라고 나타내는 팝업이 표시됩니다. 9516161d8578b240.png

numSidesprivate로 표시하면 Dice 클래스 내에서만 액세스할 수 있습니다. numSides를 사용할 유일한 코드가 Dice 클래스 내에 있으므로 Dice 클래스의 경우 이 인수를 private로 만들어도 괜찮습니다. 다음 단원에서 private 변수와 public 변수에 관해 자세히 알아봅니다.

  1. Make ‘numSides' ‘private'를 클릭하여 Android 스튜디오에서 제안한 수정사항을 적용해 봅니다.

rollDice() 메서드 만들기

이제 Dice 클래스를 앱에 추가했으므로 MainActivity를 업데이트하여 클래스를 사용합니다. 코드 구성을 개선하려면 주사위 굴리기에 관한 로직을 모두 함수 하나에 배치합니다.

  1. 텍스트를 '6'으로 설정하는 클릭 리스너의 코드를 rollDice() 호출로 바꿉니다.
rollButton.setOnClickListener {
   rollDice()
}
  1. rollDice()가 아직 정의되지 않았으므로 Android 스튜디오에서는 오류를 표시하고 rollDice()를 빨간색으로 표시합니다.
  2. rollDice() 위로 포인터를 가져가면 Android 스튜디오에서는 문제와 가능한 해결 방법을 표시합니다.

21ef4d7c6c33e154.png

  1. More actions...를 클릭하면 메뉴가 표시됩니다. Android 스튜디오는 더 많은 작업을 지원합니다.

16bb603205fc3d3.png

  1. Create function ‘rollDice'를 선택합니다. Android 스튜디오는 MainActivity 내부 함수의 빈 정의를 만듭니다.
private fun rollDice() {
    TODO("Not yet implemented")
}

새 Dice 객체 인스턴스 만들기

이 단계에서는 rollDice() 메서드로 주사위를 만들고 굴려 TextView에 그 결과를 표시합니다.

  1. rollDice() 내에서 TODO() 호출을 삭제합니다.
  2. 6면 주사위를 만드는 코드를 추가합니다.
val dice = Dice(6)
  1. roll() 메서드를 호출하여 주사위를 굴리고 diceRoll이라는 변수에 결과를 저장합니다.
val diceRoll = dice.roll()
  1. findViewById()를 호출하여 TextView를 찾습니다.
val resultTextView: TextView = findViewById(R.id.textView)

diceRoll 변수는 숫자이지만 TextView는 텍스트를 사용합니다. diceRoll에서 toString() 메서드를 사용하여 문자열로 변환할 수 있습니다.

  1. diceRoll을 문자열로 변환하고 이를 사용하여 resultTextView의 텍스트를 업데이트합니다.
resultTextView.text = diceRoll.toString()

rollDice() 메서드는 다음과 같이 표시됩니다.

private fun rollDice() {
    val dice = Dice(6)
    val diceRoll = dice.roll()
    val resultTextView: TextView = findViewById(R.id.textView)
    resultTextView.text = diceRoll.toString()
}
  1. 앱을 실행하면 주사위 굴리기 결과는 6이 아닌 다른 값으로 변경됩니다. 1에서 6 사이의 랜덤 숫자이므로 값 6이 표시될 수도 있습니다.

bbf0d6a6579100b9.png 276d8f65e4914c4c.png

잘하셨습니다.

7. 적절한 코딩 사례 채택

앱이 작동하도록 여기저기 수정하다 보면 코드가 좀 지저분해 보일 수 있습니다. 따라서 코드를 완성하기 전에 간단한 정리 작업을 해야 합니다. 그러면 앱 상태가 좋아지고 앞으로 유지하기도 더 쉬워집니다.

이러한 습관은 전문 Android 개발자가 코드를 작성할 때 연습하는 것입니다.

Android 스타일 가이드

팀으로 작업할 때 팀원들은 유사한 방식으로 코드를 작성하여 코드 전체에서 일관성이 유지되도록 하는 것이 좋습니다. 이런 이유로 Android에는 Android 코드 작성 방법에 관한 스타일 가이드(이름 지정 규칙, 서식 지정 및 준수할 기타 우수 사례 등)가 있습니다. Android 코드를 작성할 때 다음 가이드라인을 준수하세요. Android 개발자용 Kotlin 스타일 가이드

다음은 스타일 가이드를 준수하는 방법입니다.

코드 정리

코드 압축

코드를 더 적은 수의 줄로 압축하여 더 간결하게 만들 수 있습니다. 예를 들어 다음은 Button에서 클릭 리스너를 설정하는 코드입니다.

rollButton.setOnClickListener {
    rollDice()
}

클릭 리스너의 명령 길이가 한 줄뿐이므로 rollDice() 메서드 호출과 중괄호를 모두 한 줄로 압축할 수 있습니다. 다음과 같습니다. 세 줄이 한 줄이 되었습니다.

rollButton.setOnClickListener { rollDice() }

코드 서식 다시 지정

이제 Android의 권장 코드 서식 지정 규칙을 준수하도록 코드의 서식을 다시 지정합니다.

  1. MainActivity.kt 클래스에서 Windows의 단축키 Control+A(Mac은 Command+A)를 사용하여 파일의 텍스트를 모두 선택합니다. 또는 Android 스튜디오의 메뉴 Edit > Select All로 이동할 수 있습니다.
  2. 파일의 텍스트를 모두 선택한 상태에서 Android 스튜디오 메뉴 Code > Reformat Code로 이동하거나 단축키 Ctrl+Alt+L(Mac은 Command+Option+L)을 사용합니다.

그러면 공백, 들여쓰기 간격 등의 코드 서식 지정이 업데이트됩니다. 변경사항이 없을 수 있지만 괜찮습니다. 이미 코드의 서식이 올바르게 지정된 것입니다.

코드에 주석 달기

코드에 주석을 추가하여 작성한 코드에서 발생하는 작업을 설명합니다. 코드가 점점 복잡해짐에 따라 이렇게 작동하도록 코드를 작성한 이유를 기록하는 것도 중요합니다. 변경하려고 나중에 코드로 돌아오면 코드가 하는 작업은 여전히 명확하지만 코드를 이렇게 작성한 이유는 기억나지 않을 수 있습니다.

작성한 각 클래스(앱에 있는 클래스는 MainActivityDice뿐임) 및 각 메서드의 주석을 추가하는 것이 일반적입니다. 주석 시작과 끝부분에 /***/ 기호를 사용하여 시스템에 코드가 아니라고 알립니다. 이러한 줄은 시스템에서 코드를 실행할 때 무시됩니다.

클래스의 주석 예

/**
* This activity allows the user to roll a dice and view the result
* on the screen.
*/
class MainActivity : AppCompatActivity() {

메서드의 주석 예

/**
* Roll the dice and update the screen with the result.
*/
private fun rollDice() {

메서드 내에서는 코드 리더에 도움이 된다면 자유롭게 주석을 추가할 수 있습니다. 주석 시작 부분에 // 기호를 사용할 수 있습니다. 줄에서 // 기호 뒤에 오는 모든 내용은 주석으로 간주됩니다.

메서드 내에 주석이 2개인 예

private fun rollDice() {
   // Create new Dice object with 6 sides and roll it
   val dice = Dice(6)
   val diceRoll = dice.roll()

   // Update the screen with the dice roll
   val resultTextView: TextView = findViewById(R.id.textView)
   resultTextView.text = diceRoll.toString()
}
  1. 잠시 시간을 내어 코드에 주석을 추가해 봅니다.
  2. 이러한 주석과 서식이 모두 변경되면 앱을 다시 실행하여 예상대로 작동하는지 확인하는 것이 좋습니다.

코드에 주석을 달 수 있는 한 가지 방법은 솔루션 코드를 참고하세요.

8. 솔루션 코드

이 Codelab의 솔루션 코드는 아래에 나온 프로젝트와 모듈에 있습니다.

이 Codelab의 코드를 가져와서 Android 스튜디오에서 열려면 다음을 실행합니다.

코드 가져오기

  1. 제공된 URL을 클릭합니다. 브라우저에서 프로젝트의 GitHub 페이지가 열립니다.
  2. 브랜치 이름이 Codelab에 지정된 브랜치 이름과 일치하는지 검토하고 확인합니다. 예를 들어 다음 스크린샷에서 브랜치 이름은 main입니다.

8cf29fa81a862adb.png

  1. 프로젝트의 GitHub 페이지에서 Code 버튼을 클릭하여 팝업을 엽니다.

1debcf330fd04c7b.png

  1. 팝업에서 Download ZIP 버튼을 클릭하여 컴퓨터에 프로젝트를 저장합니다. 다운로드가 완료될 때까지 기다립니다.
  2. 컴퓨터에서 파일을 찾습니다(예: Downloads 폴더).
  3. ZIP 파일을 더블클릭하여 압축을 해제합니다. 프로젝트 파일이 포함된 새 폴더가 만들어집니다.

Android 스튜디오에서 프로젝트 열기

  1. Android 스튜디오를 시작합니다.
  2. Welcome to Android Studio 창에서 Open을 클릭합니다.

d8e9dbdeafe9038a.png

참고: Android 스튜디오가 이미 열려 있는 경우 File > Open 메뉴 옵션을 대신 선택합니다.

8d1fda7396afe8e5.png

  1. 파일 브라우저에서 압축 해제된 프로젝트 폴더가 있는 위치로 이동합니다(예: Downloads 폴더).
  2. 프로젝트 폴더를 더블클릭합니다.
  3. Android 스튜디오가 프로젝트를 열 때까지 기다립니다.
  4. Run 버튼 8de56cba7583251f.png을 클릭하여 앱을 빌드하고 실행합니다. 예상대로 작동하는지 확인합니다.

9. 요약

  • Layout Editor를 사용하여 Android 앱에 Button을 추가합니다.
  • MainActivity.kt 클래스를 수정하여 앱에 상호작용 동작을 추가합니다.
  • Toast 메시지를 임시 솔루션으로 표시하여 제대로 작업하고 있는지 확인합니다.
  • setOnClickListener()를 사용하여 Button의 클릭 시 리스너를 설정해 Button을 클릭할 때의 동작을 추가합니다.
  • 앱이 실행 중일 때 레이아웃의 TextView, Button 또는 다른 UI 요소에서 메서드를 호출하여 화면을 업데이트할 수 있습니다.
  • 코드에 주석을 달아 다른 개발자가 코드를 읽을 때 잘 이해할 수 있도록 합니다.
  • 코드 서식을 다시 지정하고 코드를 정리합니다.

10. 자세히 알아보기

11. 연습하기

다음을 따르세요.

  1. 앱에 다른 주사위를 추가합니다. Roll 버튼을 클릭하면 주사위 두 개가 굴려집니다. 결과가 화면에서 2개의 다른 TextViews에 표시되어야 합니다.

학습 내용 확인:

완성된 앱은 오류 없이 실행되고 앱에 주사위 두 개가 표시되어야 합니다.