안드로이드 스터디

JetPack Compose 4편 : 이미지 카드 만들기

mky 2025. 12. 30. 22:44
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        //xml은 setContentView
        setContent {
            val painter = painterResource(id = R.drawable.pushpush)
            val description = "Mky makes pushpushgame"
            val title = "Mky makes pushpushgame"
            Box(modifier = Modifier
                .fillMaxWidth(0.5f)
                .padding(16.dp)) {
                ImageCard(
                    painter =painter,
                    contentDescription = description,
                    title = title,
                    //modifier = TODO()
                )
            }
        }
    }
}

@Composable
fun ImageCard(
    painter: Painter,
    contentDescription: String,
    title: String,
    modifier: Modifier = Modifier
) {
    Card(
        modifier = modifier.fillMaxWidth(),
        shape = RoundedCornerShape(15.dp),
        elevation = CardDefaults.cardElevation(5.dp)
    ) {
        Box(modifier = Modifier.height(200.dp)) {
            Image(
                painter = painter,
                contentDescription = contentDescription,
                contentScale = ContentScale.Crop,
                modifier = Modifier.fillMaxSize()

            )
            Box(modifier = Modifier
                .fillMaxSize()
                .background(
                    Brush.verticalGradient(
                        colors = listOf(
                            Color.Transparent,
                            Color.Black
                        ),
                        startY = 300f
                    )
                ))

            // 이 Box는 Image 위에 overlay 용으로 둔 것 같음
            Box(
                modifier = Modifier
                    .fillMaxSize()
                    .padding(12.dp),
                contentAlignment = Alignment.BottomStart
            ) {
                // 여기에 title Text나 다른 overlay 요소 넣기
                Text(title, style = TextStyle(color = Color.White, fontSize = 16.sp))
            }
        }
    }
}

MainActivity
 └─ setContent
     └─ Box (가로 50%, padding 16dp)
         └─ ImageCard
             └─ Card (둥근 모서리 + elevation)
                 └─ Box (height 200dp)
                     ├─ Image (fillMaxSize, Crop)
                     ├─ Box (그라데이션)
                     └─ Box (Text, BottomStart)

구조는 위와 같다.

 

몰랐던 거 정리

  1. ContentScale
    • Image를 Box나 다른 컨테이너 안에 넣으면, 이미지의 크기와 컨테이너 크기가 다를 수 있다. 이때 이미지를 컨테이너 안에 어떻게 맞출지를 contentScale로 결정할 수 있다. Compose에서는 대표적으로 세 가지가 있다.
      • ContentScale.Fit - 이미지 전체가 컨테이너 안에 들어오도록 비율 유지. 빈 공간이 생길 수 있음.
      • ContentScale.Crop - 이미지가 컨테이너를 꽉 채우도록 자르면서 비율 유지. 빈 공간 없음.
      • ContentScale.FillBounds - 컨테이너 크기에 맞춰 이미지 왜곡 가능. 비율 무시.
  2. Elevation
    1. UI 요소가 화면에서 떠 있는 정도를 의미한다.
    2. 즉, 그림자(Shadow)를 만들어서 입체감을 주는 역할이다.
    3. Material Design에서 위치 계층(Layer)과 깊이를 표현할 때 사용된다.
    4. UI에 입체감, 강조 효과를 줄 때 사용됨.
  3. Card에서 elevation
    1. CardDefaults.cardElevation(5.dp)는 카드에 5dp 높이만큼 그림자를 준다는 의미
    2. dp 값이 클수록 그림자가 진하고, 카드가 화면에서 더 “떠 있는 느낌”이 남.
  4. fillMaxSize()
    1. Modifier에서 제공하는 함수로, 말 그대로 부모 컨테이너가 가진 가로와 세로 공간을 모두 채우겠다는 의미
    2. 내부 요소가 부모 크기를 기준으로 동적으로 늘어나거나 줄어들 때 편리함.
  5. contentAlignment
    1. Box 안에서 자식(Child)을 어디에 배치할지 지정하는 속성
    2. Box는 기본적으로 겹쳐서 배치하는 레이아웃인데, 자식이 여러 개일 때 정렬 위치를 정해줄 수 있다.
    3. Alignment를 이용해 Top, Bottom, Center, Start, End 등 위치를 지정 가능

실행 결과