In my view model I have:
var uri = savedStateHandle.getStateFlow("uri", Uri.EMPTY)
private set
In my view:
val uri by viewModel.uri.collectAsState()
Image(
painter = rememberAsyncImagePainter(
ImageRequest
.Builder(LocalContext.current)
.data(data = uri)
.build()
),
contentDescription = "",
modifier = Modifier
.padding(vertical = 16.dp)
.size(avatarSize.value)
.clip(CircleShape)
,
contentScale = ContentScale.Crop
)
When I am saving new image it is saved with the same uri in local strage so my Image is not recomposed and old one is presented.
I can change uri and then image is recomposed as intended but how to inform my Image that it should be recomposed even when uri is still the same?
You can use coil's setParameter method on the builder which will reload whenever the parameter changes. You can use timestamp of last change as a parameter or something like that.
val timestamp by viewModel.timestamp.collectAsState()
ImageRequest
.Builder(LocalContext.current)
.data(data = uri)
.setParameter("timestamp", timestamp, null)
.build()
Related
I want to show picture with Coil from Uri.
Following code shows picture but when I choose one.
I want to store Uri and when Screen starts i want to show it immediately.
val uri = "content://com.android.providers.media.documents/document/image%3A18".toUri()
var imageUri by remember { mutableStateOf<Uri?>(null) }
val context = LocalContext.current
val launcher =
rememberLauncherForActivityResult(contract = ActivityResultContracts.GetContent()) {
uri: Uri? ->
imageUri = uri
}
Column {
Button(onClick = {
//here we are going to add logic for picking image
launcher.launch(
"image/*"
)
}, content = {
Text(text = "Select Image From Gallery")
})
AsyncImage(
model = ImageRequest.Builder(context = context)
.data(imageUri)
.crossfade(true)
.build(),
contentDescription = "",
contentScale = ContentScale.Crop,
modifier = Modifier
.size(144.dp)
)
Image(
painter = rememberAsyncImagePainter(imageUri),
contentDescription = "Picture",
)
val uri is uri I chooshed before and I copied it and put to string to show image.
But this way first I need to choose picture and it will show. If I put uri instead of imageUri in .data() or rememberAsyncImagePainter nothing happens.
I'm trying to fetch image uri and then display it in my application with coil.
var imageUri by remember { mutableStateOf<Uri?>(null) }
val launcher =
rememberLauncherForActivityResult(contract = ActivityResultContracts.GetContent()) { uri: Uri? ->
imageUri = uri
}
Column {
Button(onClick = {
//here we are going to add logic for picking image
launcher.launch(
"image/*"
)
}, content = {
Text(text = "Select Image From Gallery")
})
Log.d(TAG, "ClientCardItem: $imageUri")
Text(text = imageUri.toString())
I made this just to check if i fetched uri. I got result like this:
"content://com.android.providers.media.documents/document/image%3A18", i put it to string.
This is for image display:
Image(
painter = rememberImagePainter(
data = Uri.parse(uri) // or ht
)
,
contentDescription = "123",
modifier = Modifier.height(200.dp).width(200.dp),
contentScale = ContentScale.FillWidth
)
I know that I dont have .jpg or .png or something else to display it properly. My question is how to get that format to display picture I picked.
EDIT:
rememberAsyncImagePainter, rememberImagePainter or AsyncImage are not found ?
After I updated to:
implementation "io.coil-kt:coil:2.2.2"
On AsyncImage() -> Unresolved reference: AsyncImage
To display the image just use:
AsyncImage(model = imageUri, contentDescription = "Picture")
or:
Image(
painter = rememberAsyncImagePainter(imageUri),
contentDescription = "Picture",
)
I have a list of photos from the internet and I want to load them into a LazyColumn. The problem is that some of them are loading faster than others so the photos appear in random order.
Here is the code:
val state = viewModel.photos.collectAsState()
val lastIndex = state.value.lastIndex
LazyColumn {
itemsIndexed(state.value) { i, photo ->
AsyncImage(
model = photo.urls.regular,
contentDescription = null,
modifier = Modifier.fillMaxWidth(),
)
if (i >= lastIndex-1 && !viewModel.isLoading.value) {
viewModel.getPhotos(6)
}
}
}
Sometimes image with LastIndex-1 occurs first and it triggers viewModel to get new data.
How can I make a handler for loading a list of images? Or maybe any suggestions on how to make a preloading screen which will end after loading all images into LazyColumn
I also have a Coil version too:
val model = ImageRequest.Builder(LocalContext.current)
.data(photo.urls.regular)
.size(Size.ORIGINAL)
.crossfade(true)
.build()
val painter = rememberAsyncImagePainter(model)
Image(
painter = painter,
contentDescription = null,
modifier = Modifier.fillMaxWidth(),
)
Let say i have image components can show image from selected image from gallery;
#Composable
fun ClickableToGalleryImage() {
var imageUri by remember {
mutableStateOf<Uri?>(null)
}
val launcher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.GetContent()
) { uri: Uri? ->
println(imageUri)
imageUri = uri
}
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center
) {
Image(
painter = rememberAsyncImagePainter(
ImageRequest
.Builder(LocalContext.current)
.data(data = imageUri)
.build()
),
contentDescription = null,
modifier = Modifier
.clickable { launcher.launch("image/*") }
.size(100.dp)
.clip(CircleShape)
.border(2.dp, Color.Gray, CircleShape),
contentScale = ContentScale.Crop
)
}
}
this works very well.
But if i extract the imageUri value;
I/System.out: content://com.android.providers.media.documents/document/image%3A33
and manually type the imageUri variable;
Image(
painter = rememberAsyncImagePainter(
ImageRequest
.Builder(LocalContext.current)
.data(data = "content://com.android.providers.media.documents/document/image%3A33")
.build()
),
contentDescription = null,
modifier = Modifier
.size(100.dp)
.clip(CircleShape)
.border(2.dp, Color.Gray, CircleShape),
contentScale = ContentScale.Crop
)
Coil can't load picture. Why is that? And how can i show picture from gallery with uri?
Coil can't load picture. Why is that?
You do not have read permission to access the content.
And how can i show picture from gallery with uri?
Use the Uri that you get back from your ActivityResultContracts.GetContent request, in the same activity where you requested it.
If you need durable access to the content, switch to OpenDocument and call takePersistableUriPermission() on a ContentResolver, supplying the Uri.
I'm implementing a simple gallery screen using Jetpack Compose which shows all video and image thumbnails on the screen
I have displayed image from file path successfully. However, I've got trouble in showing video thumbnail. How can I do that using Coil?
Here's my code to show image thumbnails:
#Composable
fun ImageLoaderFromLocal(
url: String,
placeHolderResId: Int,
modifier: Modifier,
transformation: Transformation
) {
val painter = rememberImagePainter(data = File(url),
builder = {
placeholder(placeHolderResId)
crossfade(true)
transformations(transformation)
})
Image(
painter = painter,
contentDescription = null,
modifier = modifier,
contentScale = ContentScale.Inside
)
}
According to Coil documentation, you need to add following dependency:
implementation("io.coil-kt:coil-video:$coil_version")
and specify fetcher in the builder:
val context = LocalContext.current
val painter = rememberImagePainter(
data = url,
builder = {
fetcher(VideoFrameUriFetcher(context))
// optionally set frame location
videoFrameMillis(1000)
placeholder(placeHolderResId)
crossfade(true)
transformations(transformation)
}
)
The other answer doesn't really work any more.
so i tried this one and it worked
val context = LocalContext.current
var visible by rememberSaveable { mutableStateOf(false) }
val imageLoader = ImageLoader.Builder(context)
.components {
add(VideoFrameDecoder.Factory())
}.crossfade(true)
.build()
val painter = rememberAsyncImagePainter(
model = "Your file here",
imageLoader = imageLoader,
The painter should be called in the image composable
like this
Image(
painter = painter,
contentDescription = "",
contentScale = ContentScale.Crop,
alignment = Alignment.Center,
modifier = Modifier.fillMaxSize()
)
i hope this help someone