سؤال

I need to pass a resource ID to a method in one of my classes. It needs to use both the id that the reference points to and also it needs the string. How should I best achieve this?

For example:

R.drawable.icon

I need to get the integer ID of this, but I also need access to the string "icon".

It would be preferable if all I had to pass to the method is the "icon" string.

هل كانت مفيدة؟

المحلول

@EboMike: I didn't know that Resources.getIdentifier() existed.

In my projects I used the following code to do that:

public static int getResId(String resName, Class<?> c) {

    try {
        Field idField = c.getDeclaredField(resName);
        return idField.getInt(idField);
    } catch (Exception e) {
        e.printStackTrace();
        return -1;
    } 
}

It would be used like this for getting the value of R.drawable.icon resource integer value

int resID = getResId("icon", R.drawable.class); // or other resource class

I just found a blog post saying that Resources.getIdentifier() is slower than using reflection like I did. Check it out.

نصائح أخرى

You can use this function to get resource ID.

public static int getResourceId(String pVariableName, String pResourcename, String pPackageName) 
{
    try {
        return getResources().getIdentifier(pVariableName, pResourcename, pPackageName);
    } catch (Exception e) {
        e.printStackTrace();
        return -1;
    } 
}

So if you want to get for drawable call function like this

getResourceId("myIcon", "drawable", getPackageName());

and for string you can call it like this

getResourceId("myAppName", "string", getPackageName());

Read this

This is based on @Macarse answer.

Use this to get the resources Id in a more faster and code friendly way.

public static int getId(String resourceName, Class<?> c) {
    try {
        Field idField = c.getDeclaredField(resourceName);
        return idField.getInt(idField);
    } catch (Exception e) {
        throw new RuntimeException("No resource ID found for: "
                + resourceName + " / " + c, e);
    }
}

Example:

getId("icon", R.drawable.class);

How to get an application resource id from the resource name is quite a common and well answered question.

How to get a native Android resource id from the resource name is less well answered. Here's my solution to get an Android drawable resource by resource name:

public static Drawable getAndroidDrawable(String pDrawableName){
    int resourceId=Resources.getSystem().getIdentifier(pDrawableName, "drawable", "android");
    if(resourceId==0){
        return null;
    } else {
        return Resources.getSystem().getDrawable(resourceId);
    }
}

The method can be modified to access other types of resources.

If you need to pair a string and an int, then how about a Map?

static Map<String, Integer> icons = new HashMap<String, Integer>();

static {
    icons.add("icon1", R.drawable.icon);
    icons.add("icon2", R.drawable.othericon);
    icons.add("someicon", R.drawable.whatever);
}

You can use Resources.getIdentifier(), although you need to use the format for your string as you use it in your XML files, i.e. package:drawable/icon.

I did like this, it is working for me:

    imageView.setImageResource(context.getResources().
         getIdentifier("drawable/apple", null, context.getPackageName()));

Since you said you only wanted to pass one parameter and it did not seem to matter which, you could pass the resource identifier in and then find out the string name for it, thus:

String name = getResources().getResourceEntryName(id);

This might be the most efficient way of obtaining both values. You don't have to mess around finding just the "icon" part from a longer string.

A simple way to getting resource ID from string. Here resourceName is the name of resource ImageView in drawable folder which is included in XML file as well.

int resID = getResources().getIdentifier(resourceName, "id", getPackageName());
ImageView im = (ImageView) findViewById(resID);
Context context = im.getContext();
int id = context.getResources().getIdentifier(resourceName, "drawable",
context.getPackageName());
im.setImageResource(id);
Simple method to get resource ID:

public int getDrawableName(Context ctx,String str){
    return ctx.getResources().getIdentifier(str,"drawable",ctx.getPackageName());
}

In MonoDroid / Xamarin.Android you can do:

 var resourceId = Resources.GetIdentifier("icon", "drawable", PackageName);

But since GetIdentifier it's not recommended in Android - you can use Reflection like this:

 var resourceId = (int)typeof(Resource.Drawable).GetField("icon").GetValue(null);

where I suggest to put a try/catch or verify the strings you are passing.

In your res/layout/my_image_layout.xml

<LinearLayout ...>
    <ImageView
        android:id="@+id/row_0_col_7"
      ...>
    </ImageView>
</LinearLayout>

To grab that ImageView by its @+id value, inside your java code do this:

String row = "0";
String column= "7";
String tileID = "row_" + (row) + "_col_" + (column);
ImageView image = (ImageView) activity.findViewById(activity.getResources()
                .getIdentifier(tileID, "id", activity.getPackageName()));

/*Bottom code changes that ImageView to a different image. "blank" (R.mipmap.blank) is the name of an image I have in my drawable folder. */
image.setImageResource(R.mipmap.blank);  

The Kotlin approach

inline fun <reified T: Class<R.drawable>> T.getId(resourceName: String): Int {
            return try {
                val idField = getDeclaredField (resourceName)
                idField.getInt(idField)
            } catch (e:Exception) {
                e.printStackTrace()
                -1
            }
        }

Usage:

val resId = R.drawable::class.java.getId("icon")

For getting Drawable id from String resource name I am using this code:

private int getResId(String resName) {
    int defId = -1;
    try {
        Field f = R.drawable.class.getDeclaredField(resName);
        Field def = R.drawable.class.getDeclaredField("transparent_flag");
        defId = def.getInt(null);
        return f.getInt(null);
    } catch (NoSuchFieldException | IllegalAccessException e) {
        return defId;
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top