6

I am loading a photo into a Image with Jetpack Compose and Coil. I want to show a loading indicator when image is loading, that replaces the picture while it loads. However I can't manage to figure it out and get it working properly. Problem with my code is that the loading indicator is loading on top of the image (and to left, bc i have not set center alignment, but it has the same behavior with center aligmnent, jsut that it is centered on top of the image). And it forces the textview down, because of the extra items in the box.

Any ideas on how to fix this? I want to show the loading indicator in the center of the box.

Here is photos with layouts on how it looks, if it helps.

When loaded: enter image description here

When Loading: enter image description here

Here is my code:

Column {
            val painter = rememberAsyncImagePainter(
                ImageRequest.Builder(LocalContext.current).data(data = entry.imageUrl).apply(block = fun ImageRequest.Builder.() {
                    crossfade(true)
                        .transformations(
                        )
                        .build()
                }).build()
            )

            val state = painter.state
            if (state is AsyncImagePainter.State.Loading || state is AsyncImagePainter.State.Error) {
                CircularProgressIndicator(
                    color = MaterialTheme.colors.primary,
                    modifier = Modifier.scale(2f)
                )
            }

            viewModel.getImageBackgroundColor(entry.imageUrl, LocalContext.current) { color ->
                dominantColor = color
            }

            Image(
                painter = painter,
                contentDescription = entry.name,
                modifier = Modifier
                    .size(120.dp)
                    .align(CenterHorizontally)
            )

            Text(
                text = entry.name,
                fontFamily = RobotoCondensed,
                fontSize = 20.sp,
                textAlign = TextAlign.Center,
                modifier = Modifier.fillMaxWidth()
            )
        }
    }

3 Answers 3

13

You can use SubcomposeAsyncImage from Coil latest version.

SubcomposeAsyncImage(
    model = image,
    contentDescription = null,
    loading = { CircularProgressIndicator() },
)
Sign up to request clarification or add additional context in comments.

1 Comment

CircularProgressIndicator() should be inside the image bounds, but it is not
9

You don't need a custom code, just use the builtin SubcomposeAsyncImage provided by the library:

SubcomposeAsyncImage(
    model = "https://example.com/image.jpg",
    loading = {
        CircularProgressIndicator()
    },
    contentDescription = stringResource(R.string.description)
)

1 Comment

identical to previous answer :)
2

You can use verticalArrangement as Center and horizontalAlignment as CenterHorizontally, which will make views inside the column scope appear in the center. Although if your use case is not to move the text view and just put the progress indicator on the center and top of the image, I will recommend putting both the image and progress indicator wrap inside a Box and giving content alignment as the center. for e.g,

Box(contentAlignment = Alignment.Center) {
    CircularProgressIndicator()
    Image()
}

1 Comment

Thanks for the help, it worked fine, I had also to add modifier = Modifier.align(CenterHorizontally) to the Box()` to also get the horizontal center alignment. `

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.