상세 컨텐츠

본문 제목

안드로이드 compose에서 pinch to zoom 만들기 (zoomable)

Android 자료실/오픈 소스

by Victorywskim 2023. 11. 25. 15:46

본문

반응형

 

 

 

 

GitHub - Baseflow/PhotoView: Implementation of ImageView for Android that supports zooming, by various touch gestures.

Implementation of ImageView for Android that supports zooming, by various touch gestures. - GitHub - Baseflow/PhotoView: Implementation of ImageView for Android that supports zooming, by various to...

github.com

기존 안드로이드의 XML 방식에서는 pinch to zoom 을 만들기 위해서는 PhotoView 라는 라이브러리를 사용했었습니다.

 

직접 구현도 고려해보긴 했었지만, 자잘한 예외처리부터 해서 지속적으로 유지보수를 하기에는 부담이 있던 탓에 라이브러리를 사용하게 되었습니다.

 

 

멀티터치: 화면 이동, 확대/축소, 회전  |  Jetpack Compose  |  Android Developers

이 페이지는 Cloud Translation API를 통해 번역되었습니다. Switch to English 멀티터치: 화면 이동, 확대/축소, 회전 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 화

developer.android.com

하지만 현재는 Compose 로만 안드로이드를 개발하고 있는 상황에서 PhotoView 를 사용하기 어려운 상황에 직면하게 되었습니다. 물론 AndroidView 를 통해서 기존 안드로이드 컴포넌트를 불러와서 사용 할 수도 있겠지만 Compose 를 사용함에 있어서 새로운 방법을 찾고자 하였고, 안드로이드 개발자 페이지를 찾아보게 되었습니다.

 

 

역시 컴포즈에서는 매우 간결한 소스로 되어 있었고 저 코드를 복사 붙여넣기를 해보니 바로 동작하는 모습을 볼 수 있었습니다.

 

하지만 바로 실무에 적용하기에는 어느정도 예외처리도 필요하고 추가적인 작업도 필요합니다.

 

예를 들어 원본 이미지보다 더 축소되어서는 안되고, 확대된 상태에서 상하좌우로 움직임도 가능해야 하는 등 여러 추가적인 작업이 필요합니다.

 

제가 개발하는 서비스가 이 기능이 메인 기능이라면 당연히 작업을 진행하였겠지만, 이미지를 확대 해주는 기능 딱 이정도만 요구되는 상황입니다.

 

직접 기능을 개발하기에는 배보다 배꼽이 더 크다고 느꼈고 오픈소스를 찾다보니 다음과 같은 라이브러리를 찾게 되었습니다.

 

GitHub - usuiat/Zoomable: Jetpack Compose library that enables contents zooming with pinch gesture.

Jetpack Compose library that enables contents zooming with pinch gesture. - GitHub - usuiat/Zoomable: Jetpack Compose library that enables contents zooming with pinch gesture.

github.com

 

 

적용 방법은 다음과 같습니다.

 

1. dependency 를 추가합니다.

repositories {
    mavenCentral()
}

dependencies {
    implementation "net.engawapg.lib:zoomable:1.5.2"
}

 

2. compose 코드를 작성합니다.

val painter = painterResource(id = R.drawable.penguin)
val zoomState = rememberZoomState(contentSize = painter.intrinsicSize)
Image(
    painter = painter,
    contentDescription = "Zoomable image",
    contentScale = ContentScale.Fit,
    modifier = Modifier
        .fillMaxSize()
        .zoomable(zoomState),
)

 

위와 같이 아주 간단하게 적용이 가능합니다.

 

하지만 여기서 끝나면 좀 아쉬운게 소개해드린 Github 페이지에서는 drawable 만 가지고 사용 방법을 소개하고 있습니다.

 

우리가 실무에서 필요한 것은 drawable 이 아니라 Bitmap 이나 Server Image 를 적용하는 부분일 것입니다.

 

저는 Coil 이라는 이미지 라이브러리를 사용하고 있으니, Coil 에 대한 정보가 필요하신 분은 다음 포스팅을 참고 바랍니다.

 

안드로이드 compose에서 Image 최적화하여 노출하기 (coil)

Coil Overview An image loading library for Android backed by Kotlin Coroutines. Coil is: Fast: Coil performs a number of optimizations including memory and disk caching, downsampling the image in memory, automatically pausing/cancelling requests, and more.

victorywskim.tistory.com

 

3. Coil 라이브러리를 이용해서 다시 Compose 코드를 작성합니다.

val zoomState = rememberZoomState()
AsyncImage(
    model = ImageRequest.Builder(LocalContext.current).data("https://example.com/image.jpg")
        .build(),
    contentDescription = null,
    contentScale = ContentScale.Fit,
    onSuccess = { state ->
        zoomState.setContentSize(state.painter.intrinsicSize)
    },
    modifier = Modifier
        .fillMaxSize()
        .zoomable(zoomState)
)

 

이와 같이 적용하시면 pinch to zoom 이 원활하게 동작하는 것을 확인 하실 수 있습니다.

 

감사합니다.

 

반응형

관련글 더보기