Development/Android

[Compose] 둥근 테두리 Image Load View 구현

SeungYong.Lee 2025. 4. 24. 15:28
반응형

- 지정된 Ratio 조건을 가지는 둥근 테두리 모양의 이미지 렌더링 컴포넌트를 작업했다.

 

- Ratio는 가로 세로 비율인데, 디자인 가이드에 1:2, 16:9 형식처럼 디자이너분이 지정을 해주셨고, 그에 따라 Enum Class로 정리했다.

enum class CustomRatio(val width: Int, val height: Int, ...) {
    RATIO_1_1(1, 1, ...),
    RATIO_4_5(4, 5, ...),
    ...

 

- 그리고 Float 타입으로 Ratio 값을 구하는 공식 함수도 선언해 준다.

val value: Float
    get() = width.toFloat() / height

 

- 둥근 테두리 구성을 위해 Modifier의 border를 사용했다. width, color, shape 지정이 가능하다.

if (withBorder) Modifier.border(
    width = 1.dp,
    color = colorResource(R.color.line_default),
    shape = RoundedCornerShape(radius))

- 굵기는 1dp, 둥근 모양을 위해 RoundedCornerShape를 활용했다.

 

- 이미지를 렌더링 해줄 Coil의 Image 컴포저블의 경우 data를 Any 타입으로 받아 리소스, url에 상관없이 처리가 가능하도록 구성했다.

Image(
    painter = rememberAsyncImagePainter(
        ImageRequest.Builder(context)
            .data(data)
            .apply { size(Size.ORIGINAL) }
            .build(),
        imageLoader = imageLoader
    ),
    contentDescription = null,
    contentScale = ContentScale.Crop,
    modifier = Modifier.fillMaxSize()
)

- ContentScale은 최대한 채울 수 있도록 Crop 처리

 

- 대략적인 전체 코드는 아래와 같다. 이를 통해 테두리가 있는 특정 비율의 이미지뷰 컴포저블 구성

@Composable
fun CustomImageView(
    context: Context,
    data: Any?,
    .....
) {
    val imageLoader = ImageLoader.Builder(context)
        .components {
            if (SDK_INT >= 28) {
                add(ImageDecoderDecoder.Factory())
            } else {
                add(GifDecoder.Factory())
            }
        }.build()
    Box(
        modifier = Modifier
            .fillMaxSize()
            .aspectRatio(ratio.value)
            .....
    ) {
        Image(
            painter = rememberAsyncImagePainter(
                ImageRequest.Builder(context)
                    .data(data)
                    .apply { size(Size.ORIGINAL) }
                    .build(),
                imageLoader = imageLoader
            ),
            contentDescription = null,
            contentScale = ContentScale.Crop,
            modifier = Modifier.fillMaxSize()
        )
    }
}
반응형