깨알 개념/Android

[Android] Jetpack Compose - Surface

interfacer_han 2024. 7. 22. 01:32

#1 개요

 

androidx.compose.material3  |  Android Developers

androidx.compose.desktop.ui.tooling.preview

developer.android.com

Surface는 Composable들의 컨테이너로, Composable의 집합을 시각적으로 표현하기 쉽게 도와준다.

 

#2 구조

@Composable
@ComposableInferredTarget
public fun Surface(
    modifier: Modifier, // Surface에 적용될 Modifier
    shape: Shape, // Surface의 모양 정의
    color: Color, // 배경색
    contentColor: Color, // Surface 속 Composable들에게 적용될 기본 색 일괄 지정.
    tonalElevation: Dp, // 색상 톤(tone)에 의한 시각적 계층화(Elevation)
    shadowElevation: Dp, // 그림자의 크기에 의한 시각적 계층화(Elevation)
    border: BorderStroke?, // 우리가 잘 아는 그 border
    content: @Composable () -> Unit
): Unit

Surface의 구조다. 각 매개변수에 대한 설명은 다음과 같다.

 

modifier
Modifier를 지정한다.

 

shape

RoundedCornerShape, CircleShape 등으로 Surface의 모양을 지정한다.

 

color
배경색이다.

 

contentColor

Surface 속에 있는 content들에 색을 명시하지 않을 때 기본적으로 적용될 색이다.

 

tonalElevation

Surface 끼리 중첩된 경우 색(tone)을 통해 중첩된 Surface 계층을 시각화한다. 하지만 조건이 있는데 바로, 가장 상위에 존재하는 Surface의 color 속성이 ColorScheme.surface로 지정되어 있어야 한다. #3 및 #4를 보면 이해가 쉽다.

 

shadowElevation

Surface에 그림자 효과를 부여한다.

 

border

테두리를 정의한다.

 

content

Surface 내부의 자식들이다. 람다 표현식(이 글의 #2-5 참조) 형태로, Surface( ... ) { ... }의 구조에서 중괄호 부분이 바로 이 content다.

 

Surface의 모든 매개변수를 전부 이용한 프로젝트를 아래에서 만들어본다.

 

#3 3개의 Surface를 중첩한 코드

// package com.example.surface

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.LocalAbsoluteTonalElevation
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.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.example.surface.ui.theme.SurfaceTheme

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            SurfaceTheme {
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background, // ColorScheme은 '색상 모음'이다.
                    tonalElevation = 0.dp, // <- 이게 기본값이라 생략해도 됨
                    border = BorderStroke(8.dp, Color.Red)
                ) {
                    Box(
                        modifier = Modifier.fillMaxSize(), // <- 이게 기본값이라 생략해도 됨
                        contentAlignment = Alignment.Center
                    ) {
                        Surface(
                            modifier = Modifier.fillMaxSize(0.8f),
                            shape = RoundedCornerShape(36.dp),
                            tonalElevation = LocalAbsoluteTonalElevation.current + 16.dp,
                            shadowElevation = 12.dp,
                        ) {
                            Box(
                                modifier = Modifier.fillMaxSize(), // <- 이게 기본값이라 생략해도 됨
                                contentAlignment = Alignment.Center
                            ) {
                                Surface(
                                    modifier = Modifier.fillMaxSize(0.8f),
                                    tonalElevation = LocalAbsoluteTonalElevation.current + 16.dp,
                                    contentColor = Color.Blue
                                ) {
                                    Greeting("Android")
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
    Text(
        text = "Hello $name!",
        fontSize = 24.sp,
        modifier = modifier,
    )
}

3개의 Surface를 계층 구조로 중첩시켰다. 그리고 #2의 각종 속성들을 적용시켰다.

 

#4 작동 확인

tonalElevation은 라이트모드에서는 점점 어두워지고, 다크모드에서는 점점 밝아진다.

 

#5 요약

Surface는 Composable들의 Container다.

 

#6 완성된 앱

 

android-practice/jetpack-compose/Surface at master · Kanmanemone/android-practice

Contribute to Kanmanemone/android-practice development by creating an account on GitHub.

github.com