Jetpack Compose how do i work with images when variable changes? - android

I use the composable function image. I need to use the specific image depending on the variable it gets.
it looks like the code underneath when hardcoded and this works for the specific image.
Image(
painterResource(id = R.drawable.carrot),
contentDescription = "carrot",
)
The problem is i want it to work like the picture below where recipe.image changes depending on what it gets from the database.
Image(
painterResource(id = recipe.image),
contentDescription = "recipe.name",
)
Somehow it needs the exact path to the drawable that is saved localy.
What i have tried:
I've tried to upload R.drawable.carrot directly to the database as an Integer, it saves it as something like 2400440340, when this integer gets into the painterResource it crashes.
I've tried to save the "R.drawable.carrot" directly as a string into the database but that don't work either because the painter needs an integer.
The only suggestions i can find to this problem on this site is this answer from 11 years ago:
int drawableId = getResources().getIdentifier(drawablename, "drawable", getPackageName());
imageview.setImageResource(drawableId);
I can't seem to find the functions getResources or the getIdentifier.

What i have tried: I've tried to upload R.drawable.carrot directly to the database as an Integer, it saves it as something like 2400440340, when this integer gets into the painterResource it crashes.
It crashes because this Int value in Resources is just a runtime reference, which means if you restart the app, the Resource, for example R.drawable.carrot, gets new referenced.
If you want another image in your painterResource, you have to change the value of recipe.name somewhere or you save your image binaries in the database (which is not very performant, I recommend not to do that).
You can load them over assets:
If you dont't have an assets folder, creat one in this location:
app/src/main/assets/
And then you can access it with a function like this:
fun getImageFromAssets(imageName: String): Bitmap {
val imageStream = assets.open(imageName)
val bitmap = BitmapFactory.decodeStream(imageStream)
imageStream.close()
return bitmap
}
Android Studio will suggest you to "Inline" the variable but don't do that. If you Inline the BitmapFactory at the return point, you close the Stream before you decode it.
You can now simply call the name from the database like:
val image: Bitmap = getImageFromAssets("imageName.jpg")

Related

Jetpack Compose Lottie Dynamic Text and Image

I have a json animation that I'm using with LottieAnimation, but my feature needs that I change a text and an image inside the animation in runtime.
The animation is a ranking like a podium. Then animated winner text and image are loaded from the backend. So I need to set these values.
Right now I know that TextDelegate can handle the Text problem, but it only works with View, as the old way to do it. It needs the View in constructor. I don't find a way to do this with Compose. And about the image, I have no glues.
Can someone help me?
Depending on your json file structure, you have two ways of settings an image
Place used images inside src/main/assets/lottieImages. Names should be the same as mentioned in your json file, in my case it's img_0.png.
val composition by rememberLottieComposition(
LottieCompositionSpec.RawRes(R.raw.we_accept),
imageAssetsFolder = "lottieImages"
)
Set a bitmap to key path, like I'm taking it from the resources, using dynamic properties
val bitmap = remember {
BitmapFactory.decodeResource(context.resources, R.drawable.my_image)
}
val dynamicProperties = rememberLottieDynamicProperties(
rememberLottieDynamicProperty(LottieProperty.IMAGE, bitmap, "weaccept.jpg"),
)
LottieAnimation(
composition,
dynamicProperties = dynamicProperties
)
I'm using this json as a sample animation.
As for the text, Lottie TextDelegate does not seem to be ported to compose, I suggest you create a feature request on github.

Using string interpolation to change imageView resource in Android studio Kotlin?

We can change image by name using string interpolation in Swift. Is there a way to achieve this in Kotlin? Can we change selected image programatically in Kotlin?
let image = UIIMage(named : "\(imageName)_selected")
You can:
val resourceId = resources.getIdentifier("${imagename}_selected", "drawable", packageName)
Personally, I'd go for a solution like this:
val resourceId = when (imageName) {
"image1" -> R.drawable.image1_selected
"image2" -> R.drawable.image2_selected
}
Although this is a little bit longer, it gives compile time warnings and errors, assuring you the drawable is there.
Perhaps the question is: why are you getting the string imageName? Can it be solved better?

ImageView always return blank when set programmatically

i still new to Android and want to know if there is a proper way to load image from an Input Stream.
If i load the image directly from Database the image will return the image just fine without any problem.
here my code to set ImageView Bitmap from Database :
varIDCardImageBinary = rs.getBinaryStream("IDCardImage");
classMyData.setDataInputStream(varIDCardImageBinary,"IDCardImage"); // Save Binary to a variable inside my Class
varimgIDCardView.setImageBitmap(BitmapFactory.decodeStream(classMyData.getInputStream("IDCardImage")));
Code above is working fine, And as you can see. I actually call the image AFTER i save the image into a variable.
I also put the function if the variable in my class is not empty, the ImageView Bitmap will be set from the variable without needed to call from Database again. Here is my code to call the image :
varIDCardImageBinary = classMyData.getInputStream("IDCardImage");
varimgIDCardView.setImageResource(0);
varimgIDCardView.setImageBitmap(BitmapFactory.decodeStream(varIDCardImageBinary));
And for some reason the ImageView is still BLANK, I have also tried code below to see if the Variable is empty or not :
Toast.makeText(DocumentAccountActivity.this, "Loaded From Class " + varIDCardImageBinary.toString(), Toast.LENGTH_SHORT).show();
But the result is not empty at all. Even so the ImageView still return blank. Is there anything wrong with how i set the Bitmap ? and What is the proper way to call it ?
EDITED :
I also have tried using Glide just like primo suggesting, but the result still the same.
here my code :
varIDCardImageBinary = classMyData.getInputStream("IDCardImage");
Glide.with(DocumentAccountActivity.this)
.asBitmap().load(varIDCardImageBinary).into(varimgIDCardView);
Just in case you wondering, If i call the image from Database directly. it workes just fine. But i don't want my client to load all data from database every moment they open the activity.

how to load images from resources

How can I load images from resource folder in my GridView Adapter ?
I have a 200 images in resource folder i named them as name_1.png,name_2.png.
I want to load image and text view into android gridview element and show the images according to the number from resource folder.
I am able to show the text view data but not the images.
can any one suggest me how to do this. I am thinking that I have to write code in getview method to change the image.
This is getview method that I tried
Put your images into drawable folder and reach them by name, then you access them by name.
int resourceId = context.getResources().getIdentifier(name, "drawable",
context.getPackageName());
Then you can use the resource
imageView.setImageResource(resourceId);
or
imageView.setBackgroundResource(resourceId);
just a convenient refactoring of the accepted answer if you use kotlin and like using its extensions functions:
fun ImageView.loadDrawableFromName(name:String, ctx: Context, visible:Int=View.VISIBLE){
val resId = ctx.resources.getIdentifier(name, "drawable", ctx.packageName)
this.setImageResource(resId)
this.visibility = visible
}
you can call it in both ways:
imgname="IMGNAME"
myimageview.loadDrawableFromName(imgname, ctx)
and
imgname="IMGNAME"
myimageview.loadDrawableFromName("#drawable/$imgname", ctx)

android: Variable passed for R.drawable.variableValue

iv.setImageResource(R.drawable.icon);
this line is working good for me
can I pass a variable value instead of icon
like if i have 10 images in drawable and i want to decide on runtime which image to show
can i pass the value through a variable and work it like
String variableValue = imageName;
iv.setImageResource(R.drawable.variableValue);
Resources.getIdentifier() can solve your problem.
String variableValue = imageName;
iv.setImageResource(getResources().getIdentifier(variableValue, "drawable", getPackageName()));
You could use an array to define your drawables:
int[] images = new int[2];
images[0] = R.drawables.image1;
images[1] = R.drawables.image2;
And then you can use this array to set a image at runtime:
lv.setImageResource(images[i]);
Where is is in this case either 0 to point to the first image or 1 to point to the second image of the array.
No, it won't work that way.
In your first line icon is a generated static final member of the static final class R.drawable so trying to concatenate it up like it was a String would give you a compiler error.
But you could try using
iv.setImageURI(uri);
where uri is the URI to your image, so you can use a string value here.
Also, according to the api documentation, it would be a better solution to use setImageBitmap: you should consider it based on your resources.
APIDocs:
public void setImageURI (Uri uri)
Since: API Level 1
Sets the content of this ImageView to
the specified Uri.
This does Bitmap reading and decoding
on the UI thread, which can cause a
latency hiccup. If that's a concern,
consider using
setImageDrawable(Drawable) or
setImageBitmap(Bitmap) and
BitmapFactory instead.
Parameters
uri The Uri of an image

Categories

Resources