0

The following Code A is from the official sample project.

I think Code A is wrong, I think there are two Images in the line, the left image is a real image which is displayed when it has been loaded, and the right image is a temp image which is displayed when the real iamge is loading.

So I replace Code A with Code B.

But in fact the UI displays a temp image named ic_crane_logo first, then displays real image as I expected when I run Code A. And the UI keeps to display the temp iamge when I run Code B.

What is the problem with my thinking and code?

Code A

Row(
    modifier = modifier
        .clickable { onItemClicked(item) }
        .padding(top = 12.dp, bottom = 12.dp)
) {      
    ExploreImageContainer {
        Box {
            val painter = rememberImagePainter(
                data = item.imageUrl,
                builder = {
                    crossfade(true)
                }
            )
            Image(
                painter = painter,
                contentDescription = null,
                contentScale = ContentScale.Crop,
                modifier = Modifier.fillMaxSize(),
            )

            if (painter.state is ImagePainter.State.Loading) {
                Image(
                    painter = painterResource(id = R.drawable.ic_crane_logo),
                    contentDescription = null,
                    modifier = Modifier
                        .size(36.dp)
                        .align(Alignment.Center),
                )
            }
        }
    }
  ...
}

Code B

   Row(
        modifier = modifier
            .clickable { onItemClicked(item) }
            .padding(top = 12.dp, bottom = 12.dp)
    ) {

       ExploreImageContainer {
             Box {
                val painter = rememberImagePainter(
                    data = item.imageUrl,
                    builder = {
                        crossfade(true)
                    }
                )

                if (painter.state is ImagePainter.State.Success){
                    Image(
                        painter = painter,
                        contentDescription = null,
                        contentScale = ContentScale.Crop,
                        modifier = Modifier.fillMaxSize(),
                    )
                }else{
                    Image(
                        painter = painterResource(id = R.drawable.ic_crane_logo),
                        contentDescription = null,
                        modifier = Modifier
                            .size(36.dp)
                            .align(Alignment.Center),
                    )
                }
            }
        }
        ...
    }
Phil Dukhov
  • 67,741
  • 15
  • 184
  • 220
HelloCW
  • 843
  • 22
  • 125
  • 310

1 Answers1

1

rememberImagePainter does not start loading an image.

It only starts when the corresponding Image is added to the view tree and has non-zero dimensions.

As long as it is not loaded, Image is a transparent view, and you get no performance gain by removing it from the view tree, so part Code A is completely correct.

Phil Dukhov
  • 67,741
  • 15
  • 184
  • 220