I'm developing a little* android app and have 9 buttons and 9 images, each named button_# and img#.png
My question is simple, is their a way that I can take an int whose value is between 1 and 9 and reference those objects without having 9 different ifs or a switch. I mean something like being able to do this
myint=4;
button.setImageResource(R.drawable.img.myint);
to set button's image to img4. Of course this doesn't work; I'm looking for some way of concatenating myint onto 'img' (so a string, I guess) and having that be usable to follow R.drawable.
*Just a Univ project, not terribly important but just using a bunch of switches doesn't look good, and moreover I personally doesn't like it.
Edit: Alternately, is there a way to make the images (referencable as in) an array? That's the effect I'm trying to get here anyway because I don't know of a way to use an array here, which would be easier if possible.
you can use getIdentifier to get the id of drawable in this way:
int drawableId = getResources().getIdentifier("resourceName", "drawable", getPackageName());
Related
I am building an Android(Kotlin) app which gets data from an API. Part of that data is an Image or more like a reference to an Image inside the Android app. Sadly Android does not accept names as arguments for images, so I have to send IDs(numbers). The Problem is that these IDs are changing when you add or remove a Image from the Android App and in general they do not seem to be "fixed" or unique.
My questions are:
Is there a bullet proof way to reference an Image via Text/Numbers?
Do IDs change from phone to phone? (Is ID "213226123" the same Image on every App where the app is installed?)
I could send an Image identifier made by myself and then work with a switch statement to check which image its supposed to be but this makes easy things complicated and would be incredible bad design.
You can get any resource (including images) id by name with getIdentifier method. Then you can get the resource using the id.
You can get the id of your image(s) dynamically calling the getIdentifier() method of the Resources, like this:
val id = context.resources.getIdentifier("my_image", "drawable", context.packageName)
1: For your request there is a solution but you'll have to do some mapping.
Say your API is returning images as a number: e.g.
{
...
"imageId": 243,
...
}
When setting the image, you map the imageId to the id of your drawable
imageView.setImageResource(findImageForId(myObject.imageId))
fun findImageForId(imageId: Int) = when(imageId){
1 -> return R.drawable.imageA
...
243 -> return R.drawable.imageXYZ
...
}
Id's of your drawables are generated at compile time so they won't change in between phones using the same APK. You can't be sure all your users have the same version (e.g. after an update) so you should never use your generated drawable id's to identify images
I have a pattern that I have been using a lot recently in my apps for as a way to map an Enum value to some resource. So instead of using switches in my code, I can simply ask for "The primary text colour for MyStateEnum.ACTIVE" or some such.
Right now I'm converting the full name of some enum (com.example.app.MyStateEnum.ACTIVE) into a resource name (com_example_app_mystateenum_active) and appending the "name" of the thing I want (primary_text_color) and then running that through getResources().getIdentifier(enumName+"_"+thingName, "color", getPackageName()) to give me the id I need to fetch the resource I want.
However getIdentifier() is slow compared to using R.color.com_example_app_mystateenum_active_primary_text_color so I'd like to find a better way.
I think that better way is to generate code in the exact same way R is generated so that I can more easily access the the ids. I'm thinking that something like this will work:
colors.xml:
<color name="some_name"
ex:use="primary_text_color"
ex:value="com.example.app.MyStateEnum.ACTIVE">#FF00FF</color>
<color name="some_name_default"
ex:use="primary_text_color">#FF0000</color>
something.java
int activeColor = getResources().getColor(X.color.primary_text_color.getForEnum(MyStateEnum.ACTIVE)); //#FF00FF
int activeColor = getResources().getColor(X.color.primary_text_color.getForEnum(MyStateEnum.INACTIVE)); //#FF0000
(I hate picking names, but you get the idea). I would like to have those values automatically updated like R is as well.
My problem is that I'm having a hard time finding anything suggesting where I should start. I'm not sure if its a matter of "you're asking the wrong question" or "no one has wanted to do this before so start reading the source code for the android plugin".
I'd like to group my drawables in some way that doesn't involve some crazy approach (for example reflection on the generated R class).
For example I have 10 types of some object in a game. I'd like to load them all into an array without actually copying:
enemy[0] = resources.getDrawable(R.drawable.enemy_image_0)
enemy[0].set....
enemy[1] = resources.getDrawable.....
Is there some way to group them and load in a loop? Any way to do that without getting into how R is generated and changing its structure?
Is there some way to group them and load in a loop?
Use getIdentifier() on the Resources object (which you typically get via getResources() on your activity or other Context).
Since this, under the covers, uses a "crazy approach" (specifically "reflection on the generated R class"), and since reflection is not especially speedy, please cache these values where possible.
I am trying to find the original android source code, where the android:text attribute from the layout files is resolved to the actual string referred to via #string/ (for instance: android:text="#string/hello"). The reason is the following: I have created a completely different way of setting up my layouts using a custom XML which in turn uses pre-written Widgets, an example:
<dialog name="Homepage">
<field type="Combobox" label="Enter">
</dialog>
What I want to do: I want to be able to change the label attribute in my example to: label="#string/enter" - so I can make use of the localization feature in android.
But in order to handle those #string commands, I need to know, where this is done in the original Android Source Code (on version 2.3 for instance) so I can imitate the behaviour. So far the only way I know of to obtain string resources is to use context.getString(int resID) - trouble is, how would I go about translating the String "#string/enter" to a res id? I assume I can't, which is why i am curious about how android handles this.
I'd be really grateful if someone could point me in the right direction and I hope my explanation wasn't too confusing :) .
[..] trouble is, how would I go about translating the String "#string/enter" to a res id?
You can use Resources.getIdentifier() for that.
Small sample that gets the res id of #string/enter:
Resources r = getResources();
int resId = r.getIdentifier("enter", "string", getPackageName());
Given that the format for resources is always the same, you can parse all three arguments out of this string and fill them into getIdentifier():
#[<package_name>:]<resource_type>/<resource_name>
from Accessing Resources
I have recently started developing a game in android, never used it before and was wondering if there is a simple way of getting a set of images loaded into the application. As my current implementation involves basically
Creating an int[] array,
Storing the values of each drawable into this array, (now this has to be hand coded, so if I add any more images it has to be added programmitically)
Then itterating through each item in the array and calling BitmapFactory to get the resource.
(Unfortunately I don't have the code with me as it is at home and I am at work, but that is the jist)
So 2 questions, is there a way of getting the drawables without having to put in each item manually to the int[] - ie looking for perhaps a file name prefix and then only loading the resource with the prefix?
Which leads me to my second question because I more than just these images in my drawable resource directory, is there a way to add extra organisation (folders) to manage the files better. As currently I have loads of images within the drawable file and how would I reference these sub folders/images.
You cannot have sub folders within the resources structure. Android depends on the folder layout to determine which resource to use in what condition (localization, different screen resolutions, etc).
I'm not sure why exactly you are trying to load up a whole bunch of images, but there are a couple of (slower) methods that allow you to look up a resource by string name. If you used a naming convention for your images you could look them up that way via [Resources.getIdentifier()][1]. However, in a game performance likely matters, so you are probably better off with a more manual approach using the int IDs directly since it is much more efficient.
[1]: http://developer.android.com/reference/android/content/res/Resources.html#getIdentifier(java.lang.String, java.lang.String, java.lang.String)
I am uploading a load of images as they will be shown to user for different items. Its not a system where responsiveness is critical so its okay in terms of what I want. Though...
public int getIdentifier (String name, String defType, String defPackage)
Since: API Level 1
Return a resource identifier for the given resource name. A fully qualified resource name is of the form "package:type/entry". The first two components (package and type) are optional if defType and defPackage, respectively, are specified here.
Note: use of this function is discouraged. It is much more efficient to retrieve resources by identifier than by name.
They suggest using the resource id but if I want to add a file later on then I have to re-compile the app to include the extra file, this is where it bugs me, as the pic gets associated to an item that I have in a string array. So I can add items to the array but not the images without a change of the code.
Surely there is a function to fix this?