Как получить идентификатор ресурса с известным именем ресурса? - PullRequest
157 голосов
/ 13 августа 2010

Я хочу получить доступ к ресурсу, например, String или Drawable, по его имени, а не по его int id.

Какой метод я бы использовал для этого?

Ответы [ 8 ]

308 голосов
/ 13 августа 2010

Если я правильно понял, это то, что вы хотите

int drawableResourceId = this.getResources().getIdentifier("nameOfDrawable", "drawable", this.getPackageName());

Где «это» - это действие, написанное только для пояснения.

Если вам требуется String в strings.xml или идентификатор элемента пользовательского интерфейса, замените «drawable»

int resourceId = this.getResources().getIdentifier("nameOfResource", "id", this.getPackageName());

Я предупреждаю вас, этот способ получения идентификаторов очень медленный, используйте только там, где это необходимо.

Ссылка на официальную документацию: Resources.getIdentifier (String name, String defType, String defPackage)

131 голосов
/ 13 августа 2010

Это будет что-то вроде:

R.drawable.resourcename

Убедитесь, что у вас нет импортированного пространства имен Android.R, поскольку это может запутать Eclipse (если это то, что вы используете).

Если это не сработает, вы всегда можете использовать метод контекста getResources ...

Drawable resImg = this.context.getResources().getDrawable(R.drawable.resource);

Где this.context инициализируется как Activity, Service или любой другой Context подкласс.

Обновление:

Если это имя, которое вы хотите, класс Resources (возвращается getResources()) имеет метод getResourceName(int) и getResourceTypeName(int)?

Обновление 2 :

Класс Resources имеет этот метод:

public int getIdentifier (String name, String defType, String defPackage) 

Возвращает целое число указанного имени ресурса, типа и пакета.

23 голосов
/ 14 мая 2012
int resourceID = 
    this.getResources().getIdentifier("resource name", "resource type as mentioned in R.java",this.getPackageName());
11 голосов
/ 27 апреля 2015

Простой способ получения идентификатора ресурса из строки.Здесь resourceName - это имя ресурса ImageView в папке для рисования, которое также включено в XML-файл.

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);
8 голосов
/ 29 сентября 2018

Kotlin Version через Extension Function

Чтобы найти идентификатор ресурса по его имени В Kotlin добавьте следующий фрагмент кода в файл kotlin:

ExtensionFunctions.kt

import android.content.Context
import android.content.res.Resources

fun Context.resIdByName(resIdName: String?, resType: String): Int {
    resIdName?.let {
        return resources.getIdentifier(it, resType, packageName)
    }
    throw Resources.NotFoundException()
}

Usage

Теперь все идентификаторы ресурсов доступны везде, где у вас есть контекстная ссылка, используя метод resIdByName:

val drawableResId = context.resIdByName("ic_edit_black_24dp", "drawable")
val stringResId = context.resIdByName("title_home", "string")
.
.
.    
6 голосов
/ 29 августа 2011

Я бы предложил вам использовать мой метод для получения идентификатора ресурса.Это намного эффективнее, чем использование метода getIdentidier (), который работает медленно.

Вот код:

/**
 * @author Lonkly
 * @param variableName - name of drawable, e.g R.drawable.<b>image</b>
 * @param с - class of resource, e.g R.drawable.class or R.raw.class
 * @return integer id of resource
 */
public static int getResId(String variableName, Class<?> с) {

    Field field = null;
    int resId = 0;
    try {
        field = с.getField(variableName);
        try {
            resId = field.getInt(null);
        } catch (Exception e) {
            e.printStackTrace();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return resId;

}
0 голосов
/ 27 июня 2017

в дополнение к @lonkly решение

  1. см. Отражения и доступность полей
  2. ненужные переменные

метод:

/**
 * lookup a resource id by field name in static R.class 
 * 
 * @author - ceph3us
 * @param variableName - name of drawable, e.g R.drawable.<b>image</b>
 * @param с            - class of resource, e.g R.drawable.class or R.raw.class
 * @return integer id of resource
 */
public static int getResId(String variableName, Class<?> с)
                     throws android.content.res.Resources.NotFoundException {
    try {
        // lookup field in class 
        java.lang.reflect.Field field = с.getField(variableName);
        // always set access when using reflections  
        // preventing IllegalAccessException   
        field.setAccessible(true);
        // we can use here also Field.get() and do a cast 
        // receiver reference is null as it's static field 
        return field.getInt(null);
    } catch (Exception e) {
        // rethrow as not found ex
        throw new Resources.NotFoundException(e.getMessage());
    }
}
0 голосов
/ 30 июня 2016

Я нашел этот класс очень полезным для работы с ресурсами.У него есть несколько определенных методов для работы с размерами, цветами, рисованными объектами и строками, как этот:

public static String getString(Context context, String stringId) {
    int sid = getStringId(context, stringId);
    if (sid > 0) {
        return context.getResources().getString(sid);
    } else {
        return "";
    }
}
...