구성 가능한 함수 text로 간단한 앱 빌드

1. 시작하기 전에

이 Codelab에서는 Jetpack Compose를 사용하여 화면에 생일 축하 메시지를 표시하는 간단한 Android 앱을 빌드합니다.

기본 요건

  • Android 스튜디오에서 앱을 만드는 방법을 알아야 합니다.
  • 에뮬레이터 또는 Android 기기에서 앱을 실행하는 방법을 알아야 합니다.

학습할 내용

  • 구성 가능한 함수를 작성하는 방법(예: 구성 가능한 함수 Text, Column, Row)
  • 앱의 텍스트를 레이아웃으로 표시하는 방법
  • 텍스트 형식을 지정하는 방법(예: 텍스트 크기 변경)

빌드할 항목

  • 텍스트 형식으로 생일 축하 메시지를 표시하는 Android 앱입니다. 작업을 완료하면 아래 스크린샷과 같이 표시됩니다.

fdf3fc55ab1d348a.png

필요한 항목

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

2. Happy Birthday 앱 설정

이 작업에서는 Android 스튜디오에서 Empty Activity 템플릿을 사용하여 프로젝트를 설정하고 텍스트 메시지를 맞춤설정된 생일 축하 표현으로 변경합니다.

Empty Activity 프로젝트 만들기

  1. Welcome to Android Studio 대화상자에서 New Project를 선택합니다.
  2. New Project 대화상자에서 Empty Activity를 선택한 다음 Next를 클릭합니다.
  3. Name 필드에 Happy Birthday를 입력한 다음 Minimum SDK 필드에서 최소 API 수준 24(Nougat)를 선택하고 Finish를 클릭합니다.

ff60c8aef54e55e5.png

  1. Android 스튜디오가 프로젝트 파일을 생성하고 프로젝트를 빌드할 때까지 기다립니다.
  2. fd26b2e3c2870c3.png Run 'app'을 클릭합니다.

앱은 아래 스크린샷과 같이 표시됩니다.

51ca4dec519ee45c.png

Empty Activity 템플릿으로 Happy Birthday 앱을 만들면 Android 스튜디오에서는 화면에 표시되는 Hello Android! 메시지를 비롯하여 기본 Android 앱의 리소스를 설정합니다. 이 Codelab에서는 메시지 위치를 정하는 방법, 기존 텍스트를 생일 축하 메시지로 바꾸는 방법, 메시지를 추가하고 형식을 지정하는 방법을 알아봅니다.

사용자 인터페이스(UI)란 무엇인가요?

앱의 사용자 인터페이스(UI)는 화면에 표시되는 텍스트, 이미지, 버튼, 기타 여러 유형의 요소 및 화면에 표시되는 방식입니다. 즉, 앱이 콘텐츠를 사용자에게 표시하는 방식이자 사용자가 앱과 상호작용하는 방식입니다.

이 이미지에는 클릭 가능한 버튼, 텍스트 메시지, 사용자가 데이터를 입력할 수 있는 텍스트 입력란이 포함됩니다.

cb6997dfd11668c4.png

클릭 가능한 버튼

50a9b402fd9037c0.png

카드 내부의 문자 메시지

17794ea52cfb5473.png

텍스트 입력란

이러한 각각의 요소를 UI 구성요소라고 합니다. 앱 화면에 표시되는 대부분의 내용은 UI 요소(UI 구성요소라고도 함)입니다. UI 요소는 상호작용이 가능한 요소(예: 클릭 가능한 버튼이나 편집 가능한 입력란)가 될 수도 있고 장식용 이미지가 될 수도 있습니다.

다음 앱에서 UI 구성요소를 최대한 많이 찾아보세요.

추천 앱 표시

이 Codelab에서는 텍스트를 표시하는 UI 요소인 Text 요소를 사용합니다.

3. Jetpack Compose란 무엇인가요?

Jetpack Compose는 Android UI를 빌드하기 위해 사용하는 최신 툴킷입니다. Compose는 적은 양의 코드, 강력한 도구 및 직관적인 Kotlin 기능으로 Android에서 UI 개발을 간소화하고 가속합니다. Compose를 사용하면 데이터를 받아서 UI 요소를 설명하는 함수, 즉 구성 가능한 함수라는 함수 집합을 정의하여 UI를 빌드할 수 있습니다.

구성 가능한 함수

구성 가능한 함수는 Compose에서 UI의 기본 빌드 블록입니다. 구성 가능한 함수의 특징은 다음과 같습니다.

  • UI 일부를 설명합니다.
  • 아무것도 반환하지 않습니다.
  • 몇 개의 입력을 받아서 화면에 표시되는 내용을 생성합니다.

주석

주석은 코드에 추가 정보를 첨부하는 방법입니다. 이 정보는 Jetpack Compose 컴파일러와 같은 도구 및 다른 개발자가 앱의 코드를 이해하는 데 도움이 됩니다.

주석은 주석 처리하고 있는 선언의 시작 부분에 @ 문자를 이름(주석)의 접두사로 추가하여 적용합니다. 속성, 함수, 클래스를 비롯한 다양한 코드 요소에 주석을 달 수 있습니다. 클래스에 관해서는 이 과정 후반부에서 알아보겠습니다.

다음 다이어그램은 주석 처리된 함수의 예입니다.

구성 가능한 함수의 구조를 보여주는 다이어그램으로, 함수 선언 앞에 있는 접두사 문자 @ 주석은 구성 가능 함수임을 나타냅니다.

다음 코드 스니펫에는 주석 처리된 속성의 예가 나와 있습니다. 이러한 내용은 향후 Codelab에서 사용할 예정입니다.

// Example code, do not copy it over

@Json
val imgSrcUrl: String

@Volatile
private var INSTANCE: AppDatabase? = null

매개변수가 있는 주석

주석은 매개변수를 받을 수 있습니다. 매개변수는 주석을 처리하는 도구에 추가 정보를 제공합니다. 다음은 @Preview 주석에 매개변수가 있는 예와 매개변수가 없는 예입니다.

코드와 미리보기를 보여주는 Android 스튜디오 스크린샷

매개변수가 없는 주석

코드와 미리보기를 보여주는 Android 스튜디오 스크린샷

배경을 미리 보여주는 주석

코드와 미리보기를 보여주는 Android 스튜디오 스크린샷

미리보기 제목으로 주석 달기

아래와 같이 여러 인수를 주석에 전달할 수 있습니다.

fd2ad3c2e7c8a9c7.png

미리보기 제목 및 시스템 UI(휴대전화 화면)를 포함하는 주석

Jetpack Compose에는 다양한 내장 주석이 포함되어 있습니다. 지금까지 이 과정에서 @Composable@Preview 주석을 이미 살펴봤습니다. 주석과 주석의 사용법은 과정의 후반부에서 알아보겠습니다.

구성 가능한 함수의 예

구성 가능한 함수는 @Composable 주석으로 주석 처리됩니다. 모든 구성 가능한 함수에는 이 주석이 있어야 합니다. 이 주석을 통해 이 함수가 데이터를 UI로 변환하게 되어 있다는 것을 Compose 컴파일러에 알립니다. 참고로 컴파일러는 작성한 코드를 한 줄씩 보고 컴퓨터가 이해할 수 있는 내용(기계어)으로 변환하는 특수 프로그램입니다.

이 코드 스니펫은 전달된 데이터(함수 매개변수 name)를 사용하여 화면에 텍스트 요소를 렌더링하는 구성 가능한 함수의 예입니다.

@Composable
fun Greeting(name: String) {
    Text(text = "Hello $name!")
}

구성 가능한 함수에 관한 몇 가지 참고사항은 다음과 같습니다.

  • Jetpack Compose는 구성 가능한 함수를 중심으로 빌드되었습니다. 이러한 함수를 사용하면 UI의 구성 과정에 집중하기보다는 앱의 모양을 설명하여 앱의 UI를 프로그래매틱 방식으로 정의할 수 있습니다. 구성 가능한 함수를 만들려면 함수 이름에 @Composable 주석을 추가하기만 하면 됩니다.
  • 구성 가능한 함수는 인수를 허용하여 앱 로직이 UI를 설명하거나 수정할 수 있게 해줍니다. 위의 경우 UI 요소가 String을 허용하므로 사용자에게 이름으로 인사할 수 있습니다.

코드에 있는 구성 가능한 함수 확인

  1. Android 스튜디오에서 MainActivity.kt 파일을 엽니다.
  2. GreetingPreview() 함수로 스크롤합니다. 이 구성 가능한 함수는 Greeting() 함수를 미리 보는 데 도움이 됩니다. 함수의 기능을 설명하도록 함수의 이름을 지정하거나 변경하는 것이 좋습니다. 이 함수의 이름을 BirthdayCardPreview()로 변경합니다.
@Preview(showBackground = true)
@Composable
fun BirthdayCardPreview() {
    HappyBirthdayTheme {
        Greeting("Android")
    }
}

구성 가능한 함수는 다른 구성 가능한 함수를 호출할 수 있습니다. 이 코드 스니펫에서 미리보기 함수는 구성 가능한 함수 Greeting()을 호출하고 있습니다.

앞서 나온 함수에는 @Composable 주석 앞에 매개변수가 있는 다른 주석인 @Preview 주석도 있습니다. @Preview 주석에 전달되는 인수는 이 과정 후반부에서 자세히 알아봅니다.

구성 가능한 함수 이름

아무것도 반환하지 않으면서 @Composable 주석을 달고 있는 구성 가능한 함수는 파스칼 표기법을 사용하여 이름을 지정해야 합니다(MUST). 파스칼 표기법은 복합어에서 각 단어의 첫 글자를 대문자로 표기하는 명명 규칙입니다. 파스칼 표기법과 카멜 표기법의 차이점은 파스칼 표기법의 경우 모든 단어를 대문자로 표기한다는 것입니다. 카멜 표기법의 경우 첫 번째 단어는 대문자 또는 소문자일 수 있습니다.

Compose 함수 이름의 특징은 다음과 같습니다.

  • 명사여야 함: DoneButton()
  • 동사 또는 동사구이면 안 됨: DrawTextField()
  • 명사화된 전치사이면 안 됨: TextFieldWithLink()
  • 형용사이면 안 됨: Bright()
  • 부사이면 안 됨: Outside()
  • 명사 앞에는 명사를 설명하는 형용사를 붙일 수도 있음: RoundIcon()

자세한 내용은 구성 가능한 함수 이름 지정을 참고하세요.

코드 예. 복사하지 마세요.

// Do: This function is a descriptive PascalCased noun as a visual UI element
@Composable
fun FancyButton(text: String) {}

// Do: This function is a descriptive PascalCased noun as a non-visual element
// with presence in the composition
@Composable
fun BackButtonHandler() {}

// Don't: This function is a noun but is not PascalCased!
@Composable
fun fancyButton(text: String) {}

// Don't: This function is PascalCased but is not a noun!
@Composable
fun RenderFancyButton(text: String) {}

// Don't: This function is neither PascalCased nor a noun!
@Composable
fun drawProfileImage(image: ImageAsset) {}

4. Android 스튜디오의 Design 창

Android 스튜디오를 사용하면 Android 기기 또는 에뮬레이터에 앱을 설치하지 않고 IDE 내에서 구성 가능한 함수를 미리 볼 수 있습니다. 이전 과정에서 배운 것처럼 Android 스튜디오의 Design 창에서 앱이 어떻게 표시되는지 미리 볼 수 있습니다.

c284448a820d577c.png

구성 가능한 함수는 함수를 미리 볼 수 있도록 매개변수의 기본값을 제공해야 합니다. 이러한 이유로 미리보기에는 Greeting() 함수를 직접 사용하지 않는 것이 좋습니다. 대신, 적절한 매개변수를 사용하여 Greeting() 함수를 호출하는 다른 함수(여기서는 BirthdayCardPreview() 함수)를 추가해야 합니다.

@Preview(showBackground = true)
@Composable
fun BirthdayCardPreview() {
    HappyBirthdayTheme {
        Greeting("Android")
    }
}

미리보기를 확인하려면 다음 단계를 따르세요.

  1. BirthdayCardPreview() 함수에서 Greeting() 함수의 "Android" 인수를 사용자 이름으로 변경합니다.
@Preview(showBackground = true)
@Composable
fun BirthdayCardPreview() {
    HappyBirthdayTheme {
        Greeting("James")
    }
}
  1. 코드를 빌드합니다. 미리보기가 자동으로 업데이트됩니다.

업데이트된 미리보기가 표시됩니다.

a9d045e42c47ca1b.png

5. 새 텍스트 요소 추가

이 작업에서는 Hello $name! 인사말을 삭제하고 생일 축하 인사말을 추가합니다.

새 구성 가능한 함수 추가

  1. MainActivity.kt 파일에서 Greeting() 함수 정의를 삭제합니다. 인사말은 이 Codelab 후반부에서 자체 제작한 함수를 추가하여 표시하게 됩니다.

다음 코드 삭제

@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
    Text(
        text = "Hello $name!",
        modifier = modifier
    )
}
  1. onCreate() 함수 내에서 Greeting() 함수 호출이 이제 빨간색으로 표시됩니다. 이 빨간색은 오류를 나타냅니다. 이 함수 호출 위에 커서를 가져가면 Android 스튜디오에 오류 관련 정보가 표시됩니다.

f5635be4356320a7.png

  1. onCreate()BirthdayCardPreview() 함수에서 Greeting() 함수 호출과 함수의 인수를 함께 삭제합니다. MainActivity.kt 파일은 다음과 같습니다.
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            HappyBirthdayTheme {
                // A surface container using the 'background' color from the theme
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                }
            }
        }
    }
}

@Preview(showBackground = true)
@Composable
fun BirthdayCardPreview() {
    HappyBirthdayTheme {
    }
}
  1. BirthdayCardPreview() 함수 앞에 GreetingText()라는 새 함수를 추가합니다. 이 함수는 구성 가능한 함수 Text를 설명하는 Compose 함수가 될 것이므로 함수 앞에 @Composable 주석을 추가해야 합니다.
@Composable
fun GreetingText() {
}
  1. 구성 가능한 함수가 Modifier 매개변수를 수락하고 이 modifier를 첫 번째 하위 요소에 전달하도록 하는 것이 좋습니다. Modifier 및 하위 요소에 관해서는 후속 작업과 Codelab에서 자세히 알아봅니다. 지금은 GreetingText() 함수에 Modifier 매개변수를 추가합니다.
@Composable
fun GreetingText(modifier: Modifier = Modifier) {
}
  1. String 유형의 매개변수 message를 구성 가능한 함수 GreetingText()에 추가합니다.
@Composable
fun GreetingText(message: String, modifier: Modifier = Modifier) {
}
  1. GreetingText() 함수에 텍스트 메시지를 이름이 지정된 인수로 전달하는 Text 컴포저블을 추가합니다.
@Composable
fun GreetingText(message: String, modifier: Modifier = Modifier) {
    Text(
        text = message
    )
}

GreetingText() 함수는 UI에 텍스트를 표시합니다. 이렇게 하려면 구성 가능한 함수 Text()를 호출하면 됩니다.

함수 미리보기

이 작업에서는 Design 창에서 GreetingText() 함수를 미리 봅니다.

  1. BirthdayCardPreview() 함수 내에서 GreetingText() 함수를 호출합니다.
  2. String 인수(친구에게 전할 생일 축하 인사)를 GreetingText() 함수에 전달합니다. 원하는 경우 "Happy Birthday Sam!"과 같이 이름을 사용하여 맞춤설정할 수 있습니다.
@Preview(showBackground = true)
@Composable
fun BirthdayCardPreview() {
    HappyBirthdayTheme {
        GreetingText(message = "Happy Birthday Sam!")
    }
}
  1. Design 창에서 자동으로 업데이트됩니다. 변경사항을 미리 봅니다.

fd1260ace2f0f7b0.png

6. 글꼴 크기 변경

사용자 인터페이스에 텍스트를 추가했지만 아직 최종 앱처럼 보이지는 않습니다. 이 작업에서는 텍스트 요소의 모양에 영향을 미치는 크기, 텍스트 색상 및 기타 속성을 변경하는 방법을 알아봅니다. 다양한 글꼴 크기와 색상으로 시도해 볼 수도 있습니다.

확장 가능한 픽셀

확장 가능한 픽셀(SP)은 글꼴 크기의 측정 단위입니다. Android 앱의 UI 요소는 두 가지 측정 단위를 사용합니다. 하나는 밀도 독립형 픽셀(DP)로 추후 레이아웃에 사용하는 것이고 다른 하나는 확장 가능한 픽셀(SP)입니다. 기본적으로 SP 단위는 DP 단위와 크기가 동일하지만, 사용자가 휴대전화 설정에서 선택한 선호하는 텍스트 크기에 따라 크기가 조절됩니다.

  1. MainActivity.kt 파일에서 GreetingText() 함수의 Text() 컴포저블로 스크롤합니다.
  2. Text() 함수에fontSize 인수를 이름이 지정된 두 번째 인수로 전달하고 인수 값을 100.sp로 설정합니다.
Text(
    text = message,
    fontSize = 100.sp
)

앱을 컴파일하려면 일부 클래스 또는 속성을 가져와야 하므로 Android 스튜디오는 .sp 코드를 강조 표시합니다.

8032c2d4926903d5.png

  1. Android 스튜디오에서 강조표시된 .sp를 클릭합니다.
  2. .sp 확장자 속성을 사용할 수 있도록 팝업에서 Import를 클릭하여 androidx.compose.ui.unit.sp를 가져옵니다.
  1. 파일 상단으로 스크롤하여 import 문을 확인합니다. 여기에서는 import androidx.compose.ui.unit.sp 문이 표시되는 것을 볼 수 있습니다. 즉, Android 스튜디오에서 파일에 패키지를 추가합니다.

e073e9d3465e080c.png

  1. 글꼴 크기가 업데이트된 미리보기를 확인합니다. 메시지가 겹치는 이유는 행 높이를 지정해야 하기 때문입니다.

b001a2c51b985d0.png

  1. 행 높이를 포함하도록 Text 구성 가능한 함수를 업데이트합니다.
@Composable
fun GreetingText(message: String, modifier: Modifier = Modifier) {
    Text(
        text = message,
        fontSize = 100.sp,
        lineHeight = 116.sp,
    )
}

cefc09e773d1f29a.png

이제 다양한 글꼴 크기로 시도해 볼 수 있습니다.

7. 다른 텍스트 요소 추가

이전 작업에서는 친구에게 전할 생일 축하 메시지를 추가했습니다. 이 작업에서는 이름으로 카드에 서명합니다.

  1. MainActivity.kt 파일에서 GreetingText() 함수로 스크롤합니다.
  2. 서명을 위해 함수에 String 유형의 매개변수 from을 전달합니다.
fun GreetingText(message: String, from: String, modifier: Modifier = Modifier)
  1. 생일 축하 메시지 Text 컴포저블 뒤에 from 값으로 설정된 text 인수를 받는 또 하나의 Text 컴포저블을 추가합니다.
@Composable
fun GreetingText(message: String, from: String, modifier: Modifier = Modifier) {
    Text(
        // ...
    )
    Text(
        text = from
    )
}
  1. 이름이 지정된 fontSize 인수를 추가하고 값을 36.sp로 설정합니다.
Text(
    text = from,
    fontSize = 36.sp
)
  1. BirthdayCardPreview() 함수로 스크롤합니다.
  2. 카드에 서명(예: "From Emma")하기 위해 String 인수를 하나 더 추가합니다.
GreetingText(message = "Happy Birthday Sam!", from ="From Emma")
  1. 미리보기를 확인합니다.

ac82fe1c68eb4599.png

구성 가능한 함수는 여러 UI 요소를 설명할 수 있습니다. 그러나 개발자가 UI 요소 정렬 방법에 관한 가이드를 제공하지 않으면 Compose는 개발자가 원하지 않는 방식으로 요소를 정렬할 수도 있습니다. 예를 들어, 이전 코드는 두 컴포저블을 정렬하는 방법에 관한 가이드가 없으므로 서로 겹치는 두 텍스트 요소를 생성합니다.

다음 작업에서는 컴포저블을 행과 열로 정렬하는 방법을 알아봅니다.

8. 행과 열에 텍스트 요소 정렬

UI 계층 구조

UI 계층 구조는 포함에 기반합니다. 즉, 한 구성요소가 하나 이상의 구성요소를 포함할 수 있으며 상위 요소 및 하위 요소라는 용어가 사용되는 경우도 있습니다. 여기에서 컨텍스트는 상위 UI 요소가 하위 UI 요소를 포함하는 것이며 이 하위 UI 요소 또한 하위 UI 요소를 포함할 수 있습니다. 이 섹션에서는 상위 UI 요소 역할을 할 수 있는 Column, Row, Box 컴포저블에 관해 알아봅니다.

9270b7e10f954dcb.png

Compose의 세 가지 기본 표준 레이아웃 요소는 구성 가능한 함수인 Column, Row, Box입니다. 다음 Codelab에서는 Box 컴포저블에 관해 자세히 알아봅니다.

세로로 정렬된 3개의 요소를 보여주는 열과 가로로 정렬된 3개의 요소를 보여주는 행

Column, RowBox는 컴포저블 콘텐츠를 인수로 사용하는 구성 가능한 함수이므로 이러한 레이아웃 요소 내에 항목을 배치할 수 있습니다. 예를 들어, Row 컴포저블 내의 각 하위 요소는 한 행에 가로로 나란히 배치됩니다.

// Don't copy.
Row {
    Text("First Column")
    Text("Second Column")
}

이러한 텍스트 요소는 이 이미지에서 보는 바와 같이 화면에서 나란히 표시됩니다.

파란색 테두리는 설명하기 위한 목적으로만 사용되며 표시되지는 않습니다.

6f74a11c03564a61.png

후행 람다 문법

이전 코드 스니펫에서 구성 가능한 함수 Row에 괄호 대신 중괄호가 사용되었습니다. 이를 후행 람다 문법이라고 합니다. 람다 및 후행 람다 문법에 관해서는 이 과정의 후반부에서 자세히 알아봅니다. 지금은 흔히 사용되는 이 Compose 문법에 익숙해지세요.

Kotlin은 마지막 매개변수가 함수일 때 함수를 매개변수로 함수에 전달하는 특수한 문법을 제공합니다.

함수 매개변수가 마지막 매개변수임

함수를 이 매개변수로 전달하면 후행 람다 문법을 사용할 수 있습니다. 함수 본문을 괄호({}) 안에 함수 이름과 함께 넣는 대신 함수 이름 뒤에 괄호를 함수 본문과 함께 배치합니다. 이는 Compose에서 일반적인 사항이므로 코드가 어떻게 보이는지 잘 알고 있어야 합니다.

예를 들어 구성 가능한 함수 Row()의 마지막 매개변수는 하위 UI 요소를 설명하는 함수인 content 매개변수입니다. 텍스트 요소 세 개가 포함된 행을 만든다고 가정해 보겠습니다. 이 코드가 작동하기는 하지만 후행 람다에 이름이 지정된 매개변수를 사용하는 것은 매우 번거롭습니다.

Row(
    content = {
        Text("Some text")
        Text("Some more text")
        Text("Last text")
    }
)

content 매개변수는 함수 서명의 마지막 매개변수이며 람다 표현식으로 값을 전달하므로(지금 람다가 무엇인지 몰라도 괜찮습니다. 먼저 문법을 숙지하세요) 다음과 같이 content 매개변수와 괄호를 삭제할 수 있습니다.

Row {
    Text("Some text")
    Text("Some more text")
    Text("Last text")
}

하나의 행에 텍스트 요소 정렬

이 작업에서는 텍스트 요소가 겹치는 것을 피하기 위해 앱의 텍스트 요소를 한 행에 정렬합니다.

  1. MainActivity.kt 파일에서 GreetingText() 함수로 스크롤합니다.
  2. 두 개의 텍스트 요소가 있는 행을 표시하도록 텍스트 요소 주위에 구성 가능한 함수 Row를 추가합니다. 구성 가능한 함수 Text 2개를 선택하고 전구를 클릭합니다. Surround with widget > Surround with Row를 선택합니다.

bb8e10def9aa7b7e.png

ca2ff1086fb0802c.png

이제 함수는 다음 코드 스니펫과 같습니다.

@Composable
fun GreetingText(message: String, from: String, modifier: Modifier = Modifier) {
    Row {
        Text(
            text = message,
            fontSize = 100.sp,
            lineHeight = 116.sp,
        )
        Text(
            text = from,
            fontSize = 36.sp
        )
    }
}
  1. Android 스튜디오는 Row 함수를 자동으로 가져옵니다. 상단으로 스크롤하여 가져오기 섹션을 확인합니다. import androidx.compose.foundation.layout.Row가 추가되어 있을 것입니다.
  2. Design 창에서 업데이트된 미리보기를 확인합니다. 생일 축하 메시지의 글꼴 크기를 일시적으로 30.sp로 변경합니다.

생일 축하 메시지와 서명이 한 행에 나란히 표시됩니다.

이제 겹치는 부분이 없으므로 미리보기가 훨씬 더 좋아 보입니다. 하지만 서명할 공간이 충분하지 않으므로 원하는 경우는 아닙니다. 다음 작업에서는 이 문제를 해결하기 위해 텍스트 요소를 하나의 열에 정렬합니다.

하나의 열에 텍스트 요소 정렬

이 작업에서는 열에 텍스트 요소를 정렬하도록 GreetingText() 함수를 변경합니다. 미리보기는 아래 스크린샷과 같이 표시됩니다.

785f6c6e087b03b.png

이 작업을 직접 해보았으므로 이제 이 스니펫의 솔루션 코드와 자신의 코드를 비교해 보세요.

@Composable
fun GreetingText(message: String, from: String, modifier: Modifier = Modifier) {
    Column {
        Text(
            text = message,
            fontSize = 100.sp,
            lineHeight = 116.sp
        )
        Text(
            text = from,
            fontSize = 36.sp
        )
    }
}

Android 스튜디오에서 자동으로 가져온 패키지를 확인합니다.

import androidx.compose.foundation.layout.Column

구성 가능한 함수의 하위 요소에 수정자 매개변수를 전달해야 합니다. 즉, 수정자 매개변수를 구성 가능한 함수 Column에 전달해야 합니다.

@Composable
fun GreetingText(message: String, from: String, modifier: Modifier = Modifier) {
    Column(modifier = modifier) {
        Text(
            text = message,
            fontSize = 100.sp,
            lineHeight = 116.sp
        )
        Text(
            text = from,
            fontSize = 36.sp
        )
    }
}

9. 앱에 인사말 추가

미리보기가 만족스러우면 기기나 에뮬레이터에서 앱에 구성 가능한 함수를 추가합니다.

  1. MainActivity.kt 파일에서 onCreate() 함수로 스크롤합니다.
  2. Surface 블록에서 GreetingText() 함수를 호출합니다.
  3. GreetingText() 함수, 생일 축하 인사말 및 서명을 전달합니다.

완성된 onCreate() 함수는 다음 코드 스니펫과 같습니다.

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            HappyBirthdayTheme {
                // A surface container using the 'background' color from the theme
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    GreetingText(message = "Happy Birthday Sam!", from = "From Emma")
                }
            }
        }
    }
}
  1. 에뮬레이터에서 앱을 빌드하고 실행합니다.

433859d648d9b26.png

인사말 가운데 맞춤

  1. 인사말을 화면 중앙에 정렬하려면 verticalArrangement라는 매개변수를 추가하고 Arrangement.Center로 설정합니다. verticalArrangement에 관해서는 Codelab 후반부에서 자세히 알아봅니다.
@Composable
fun GreetingText(message: String, from: String, modifier: Modifier = Modifier) {
    Column(
        verticalArrangement = Arrangement.Center,
        modifier = modifier
    ) {
        // ...
    }
}
  1. 열 주위에 8.dp 패딩을 추가합니다. 패딩값은 4.dp 단위로 사용하는 것이 좋습니다.
@Composable
fun GreetingText(message: String, from: String, modifier: Modifier = Modifier) {
    Column(
        verticalArrangement = Arrangement.Center,
        modifier = modifier.padding(8.dp)
    ) {
        // ...
    }
}
  1. 앱을 더 돋보이게 하려면 textAlign을 사용하여 인사말 텍스트를 중앙에 정렬합니다.
Text(
    text = message,
    fontSize = 100.sp,
    lineHeight = 116.sp,
    textAlign = TextAlign.Center
)

ac614110dd73da93.png

위의 스크린샷에서는 textAlign 매개변수로 인해 인사말만 가운데 정렬되었습니다. From Emma 서명은 기본 정렬(왼쪽)로 설정되어 있습니다.

  1. 서명에 패딩을 추가하고 오른쪽으로 정렬합니다.
Text(
    text = from,
    fontSize = 36.sp,
    modifier = Modifier
        .padding(16.dp)
        .align(alignment = Alignment.End)
)

4c8c1e27bc2f6869.png

권장사항 채택

상위 구성 가능한 함수의 수정자와 함께 수정자 속성을 전달하는 것이 좋습니다. GreetingText()의 수정자 매개변수를 다음과 같이 업데이트합니다.

onCreate()

Surface(
    //...
) {
    GreetingText(
        message = "Happy Birthday Sam!",
        from = "From Emma",
        modifier = Modifier.padding(8.dp)
    )
}

GreetingText()

@Composable
fun GreetingText(message: String, from: String, modifier: Modifier = Modifier) {
    Column(
        verticalArrangement = Arrangement.Center,
        modifier = modifier
    ) {
        // ...
    }
}

에뮬레이터에서 앱을 빌드하고 실행하여 최종 결과를 확인합니다.

74dd02e4f7fa1780.png

10. 솔루션 코드 가져오기

완료된 MainActivity.kt는 다음과 같습니다.

package com.example.happybirthday

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.example.happybirthday.ui.theme.HappyBirthdayTheme

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            HappyBirthdayTheme {
                // A surface container using the 'background' color from the theme
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    GreetingText(
                        message = "Happy Birthday Sam!",
                        from = "From Emma",
                        modifier = Modifier.padding(8.dp)
                    )
                }
            }
        }
    }
}

@Composable
fun GreetingText(message: String, from: String, modifier: Modifier = Modifier) {
    Column(
        verticalArrangement = Arrangement.Center,
        modifier = modifier
    ) {
        Text(
            text = message,
            fontSize = 100.sp,
            lineHeight = 116.sp,
            textAlign = TextAlign.Center
        )
        Text(
            text = from,
            fontSize = 36.sp,
            modifier = Modifier
                .padding(16.dp)
                .align(alignment = Alignment.End)
        )
    }
}

@Preview(showBackground = true)
@Composable
fun BirthdayCardPreview() {
    HappyBirthdayTheme {
        GreetingText(message = "Happy Birthday Sam!", from = "From Emma")
    }
}

11. 결론

Happy Birthday 앱을 만들었습니다.

다음 Codelab에서는 앱에 사진을 추가하고 텍스트 요소의 정렬을 변경하여 사진을 돋보이게 합니다.

요약

  • Jetpack Compose는 Android UI를 빌드하기 위해 사용하는 최신 도구 키트입니다. Jetpack Compose는 더 적은 수의 코드, 강력한 도구, 직관적인 Kotlin API로 Android에서의 UI 개발을 간소화하고 가속합니다.
  • 앱의 사용자 인터페이스(UI)는 화면에 표시되는 텍스트, 이미지, 버튼, 기타 여러 유형의 요소입니다.
  • 구성 가능한 함수는 Compose의 기본 구성요소입니다. 구성 가능한 함수는 UI의 일부를 설명하는 함수입니다.
  • 구성 가능한 함수는 @Composable 주석으로 주석 처리됩니다. 이 주석은 이 함수가 데이터를 UI로 변환한다는 것을 Compose 컴파일러에 알려줍니다.
  • Compose의 세 가지 기본 표준 레이아웃 요소는 Column, Row,, Box입니다. 이러한 요소는 컴포저블 콘텐츠를 사용하는 구성 가능한 함수이므로 내부에 항목을 배치할 수 있습니다. 예를 들어, Row 내의 각 하위 요소는 가로로 나란히 배치됩니다.

자세히 알아보기