Coil: Loading indicator stacked on top of image instead of replacing image?
Asked Answered
T

3

5

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()
            )
        }
    }
Teador answered 2/7, 2022 at 16:18 Comment(0)
H
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()
}
Hyland answered 2/7, 2022 at 17:9 Comment(1)
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. `Teador
C
13

You can use SubcomposeAsyncImage from Coil latest version.

SubcomposeAsyncImage(
    model = image,
    contentDescription = null,
    loading = { CircularProgressIndicator() },
)
Corundum answered 4/7, 2022 at 1:44 Comment(1)
CircularProgressIndicator() should be inside the image bounds, but it is notJaffna
E
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)
)
Elfie answered 14/7, 2022 at 14:18 Comment(1)
identical to previous answer :)Urethritis
H
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()
}
Hyland answered 2/7, 2022 at 17:9 Comment(1)
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. `Teador

© 2022 - 2024 — McMap. All rights reserved.