Reputation: 45
I am trying to pass a data class which has URI profileImage value on it and I want to populate UI with that profileImage uri value. when I try to "upload" from gallery and populate UI, it works as I wanted. But when I try to pass userDetails data class to my ProfileScreen composable, and get the profileImage value in a LaunchedEffect, it gives me the correct uri value, but for some reason Coil - AsyncImage is not populating the UI with that uri value.
1- I pass userDetail data class from HomeScreen to ProfileScreen
2- at the top of the composable code block, I do LaunchedEffect to update imageUri variable to hope that I populate the UI with userDetails?.profileImage?.toUri() value
3- when I try to upload an image by selecting from gallery, it works fine. I can populate UI like that.
All I want is to populate UI when user first enters the composable. LaunchedEffect is not working for some reason. And also, when I pick image from gallery, I get it's uri value. I tried copy pasting that uri to imageUri as "urivalue".toUri() it is not working too.
How can I solve this any ideas?
@Composable
fun ProfileScreen(
onSignOut: () -> Unit,
viewModel: ProfileScreenViewModel = hiltViewModel(),
userDetails: UserModel? ) {
var imageUri by remember { mutableStateOf<Uri?>(null) }
LaunchedEffect(true) {
Log.i("MYTAG" , "IS EMPTY? ${userDetails?.profileImage?.toUri()}")
imageUri = userDetails?.profileImage?.toUri()
}
val permissionLauncher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.PickVisualMedia(),
onResult = {
imageUri = it
Log.i("MYTAG", "it $it")
}
)
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
AsyncImage(
model = imageUri ?: R.drawable.ic_user_place_holder, // Use a default image resource
contentDescription = "",
modifier = Modifier
.padding(4.dp)
.size(150.dp)
.clip(CircleShape),
contentScale = ContentScale.Crop,
)
Spacer(modifier = Modifier.height(12.dp))
Button(onClick = {
permissionLauncher.launch(
PickVisualMediaRequest(
ActivityResultContracts.PickVisualMedia.ImageOnly
)
)
}) {
Text(text = "Pick Image")
}
Spacer(modifier = Modifier.height(16.dp))
Button(onClick = onSignOut) {
Text(text = "Sign out")
}
}
}
Upvotes: 1
Views: 5167
Reputation: 2138
Try using ImageBuilder
instead of directly passing imageUri
in model
argument.
AsyncImage(
model = ImageRequest.Builder(LocalContext.current)
.data(imageUri)
.placeholder(R.drawable.ic_user_place_holder)
.build(),
contentDescription = "",
modifier = Modifier
.padding(4.dp)
.size(150.dp)
.clip(CircleShape),
contentScale = ContentScale.Crop,
)
And if this doesn't work then imageUri
might be null when image
is build. In that case, you can trigger something to do force recompose in order to build image again.
Upvotes: 2