[Coil/번역] 2.3.0
📌 implementation 'io.coil-kt:coil-compose:2.3.0’
인트로
SubcomposeAsyncImage을 다음과 같이 사용했을 때 LazyColumn 동작에서 버벅이는 이슈가 있었다.
1 | SubcomposeAsyncImage( |
1 | object CoilImageLoader { |
테스트 해보니, Coil에서는 url에 빈값이 들어올 경우 error로 넘어간다.(Glide는 빈값일 경우 네트워크를 통하지 않고 바로 placeholder를 그대로 보여준다) 그래서 스크롤 할 때마다 로딩이미지도 깜빡거리면서 다시 그려지는 모션을 보이게 되었다.
여기서 문제는 Subcomposition이었다.
1 | AsyncImage( |
평범하게 AsyncImage를 사용하여 어느정도 예상대로의 움직임을 보이도록 성공했다.
📌 이하는 Coil 공식 문서를 번역한 것입니다.
AsyncImage 컴포저블을 사용하는 예시는 다음과 같다.
1 | AsyncImage( |
model은 ImageRequest.data 값이나 ImageRequest 그 자체를 넘길 수 있다.
AsyncImage
AsyncImage는 비동기적으로 image를 요청하여 결과값을 렌더링하는 컴포저블이다. 이는 Image 컴포저블의 표준 매개변수를 동일하게 지원하고, 부가적으로 placeholder, error, fallback painters와 onLoading, onSuccess, onError 콜백을 추가 지원한다.
1 | AsyncImage( |
SubcomposeAsyncImage
SubcomposeAsyncImage는 AsyncImage의 변형이다. 이것은 Painter를 사용하는 대신 AsyncImagePainter의 상태를 API 슬롯(아래 예제에서 loading 와 같은 것)에 제공하는 subcomposition을 사용하는 데에 쓰인다. 그 예제는 다음과 같다.
1 | SubcomposeAsyncImage( |
거기에 더해, 현재 상태에 따라 렌더링하는 항목이 달라지도록 복잡한 로직을 만들 수도 있다.
1 | SubcomposeAsyncImage( |
Subcomposition은 정규 composition보다 효율이 낮다. 그래서 이 컴포저블은 높은 퍼포먼스(부드러운 스크롤 동작 등)를 요구하는 UI에서는 맞지 않을 수 있다.
If you set a custom size for the ImageRequest using ImageRequest.Builder.size (e.g. size(Size.ORIGINAL)), SubcomposeAsyncImage will not use subcomposition since it doesn’t need to resolve the composable’s constraints.
ImageRequest.Builder.size 를 사용하여 ImageRequest의 맞춤 크기를 설정하면 SubcomposeAsyncImage는 컴포저블의 제약 조건을 해결할 필요가 없으므로 하위 컴포지션을 사용하지 않습니다.
AsyncImagePainter
내부적으로 AsyncImage와 SubcomposeAsyncImage는 model을 로드할 때 AsyncImagePainter를 사용한다. 만약 Painter가 필요한데 AsyncImage를 사용할 수 없다면 rememberAsyncImagePainter를 사용할 수 있을 것이다.
1 | val painter = rememberAsyncImagePainter("https://example.com/image.jpg") |
단, rememberAsyncImagePainter는 모든 경우에서 예상대로 동작하지 않을 수 있는 하위 수준 API다.
만약 AsyncImagePainter를 렌더링하는 Image 컴포저블에 커스텀 ContentScale를 적용한다면 rememberAsyncImagePainter도 함께 세팅해야 한다. 이건 로드할 이미지의 크기를 결정하는 데에 필수적이기 때문이다.
[Coil/번역] 2.3.0