Jak uzyskać identyfikator zasobu o znanej nazwie zasobu?

Odpowiedzi:

149

Będzie to coś takiego:

R.drawable.resourcename

Upewnij się, że nie masz Android.Rzaimportowanej przestrzeni nazw, ponieważ może to zmylić Eclipse (jeśli tego właśnie używasz).

Jeśli to nie zadziała, zawsze możesz użyć getResourcesmetody kontekstu ...

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

Gdzie this.contextjest intialised jako Activity, Servicelub jakiekolwiek inne Contextpodklasy.

Aktualizacja:

Jeśli jest to żądana nazwa, Resourcesklasa (zwracana przez getResources()) ma getResourceName(int)metodę i znak getResourceTypeName(int)?

Aktualizacja 2 :

ResourcesKlasa ma tę metodę:

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

Która zwraca liczbę całkowitą określonej nazwy zasobu, wpisz & pakiet.

Wściekły
źródło
Dziękuję za odpowiedź .R.drawable.resourcename, którego używam teraz, muszę uzyskać jego wartość całkowitą, przekazując resourcename
Asuan
2
R.drawable.resourcename jest liczbą całkowitą.
Wściekły
Cześć Rabid.what mówiłeś, że to jest jakiś sposób, poprzez dostęp R.drawable wartość .resource przez przechodzącego Resouce
Asuan
potrzebuję tej wartości całkowitej, przekazując nazwę zasobu dynamicznie
Asuan
Dziękuję w ten sposób, chcę i chcę uzyskać identyfikator zasobu do rysowania. Jak to zrobię
Asuan
341

Jeśli dobrze zrozumiałem, tego właśnie chcesz

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

Gdzie „to” jest działaniem, napisanym tylko w celu wyjaśnienia.

Jeśli chcesz mieć ciąg w strings.xml lub identyfikator elementu UI, zastąp „drawable”

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

Ostrzegam, ten sposób uzyskiwania identyfikatorów jest naprawdę powolny, używaj tylko w razie potrzeby.

Link do oficjalnej dokumentacji: Resources.getIdentifier (String name, String defType, String defPackage)

Maragues
źródło
3
Jest to bardzo przydatne w kontekście pisania testów, aby upewnić się, że istnieją określone ciągi znaków itp.
Ehtesh Choudhury
1
Nie wiem stary, dodałem Log przed i po getIdentifier () ze znacznikiem czasu i pokazał mi, że jest wykonywany w 0 - 1 ms! Więc nie jest wolny, jest super szybki! Używam go do pobierania obrazów z zasobów i działa idealnie. Przetestowano na Nexus5x.
Kirill Karmazin
1
@KirillKarmazin: Nexus5X to przyzwoicie szybki telefon, a 1ms jak na takie połączenie to dość wolny. Pamiętaj, że każda ramka interfejsu użytkownika ma tylko 16 ms.
Mooing Duck
wikipedia mówi, że kotlin pojawił się po raz pierwszy w 2011 roku, jak odpowiedzieć na pytanie dotyczące tego w 2010 roku
Abhinav Chauhan
25
int resourceID = 
    this.getResources().getIdentifier("resource name", "resource type as mentioned in R.java",this.getPackageName());
user1393422
źródło
15

Kotlin VersionprzezExtension Function

Aby znaleźć identyfikator zasobu według jego nazwy W Kotlin, dodaj poniższy fragment kodu w pliku 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

Teraz wszystkie identyfikatory zasobów są dostępne wszędzie tam, gdzie masz odwołanie do kontekstu przy użyciu resIdByNamemetody:

val drawableResId = context.resIdByName("ic_edit_black_24dp", "drawable")
val stringResId = context.resIdByName("title_home", "string")
.
.
.    
aminografia
źródło
wikipedia mówi, że kotlin pojawił się po raz pierwszy w 2011 roku, czy możesz mi powiedzieć, jak to pytanie zostało zadane w 2010 roku, a zadeklarowane dla Androida w 2019 roku, w jaki sposób zadał pytanie kotlin na Androida w 2010 roku
Abhinav Chauhan
14

Prosty sposób na uzyskanie identyfikatora zasobu z ciągu. Tutaj nazwa_zasobu jest nazwą zasobu ImageView w folderze do rysowania, który jest również zawarty w pliku 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);
Muhammad Adil
źródło
6

Sugerowałbym użycie mojej metody, aby uzyskać identyfikator zasobu. Jest to o wiele bardziej wydajne niż użycie metody getIdentidier (), która jest wolna.

Oto kod:

/**
 * @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;

}
Lonkly
źródło
Nie będzie działać we wszystkich przypadkach. Na przykład, jeśli masz <string name = "string.name"> content </string>, to klasa R.string będzie miała pole string_name. Twoja metoda nie zadziała w tym momencie.
ddmytrenko
3
Twoja metoda nie jest w rzeczywistości szybka. Ponieważ serializacja klas Java nigdy nie działa szybko.
ddmytrenko
5
// image from res/drawable
    int resID = getResources().getIdentifier("my_image", 
            "drawable", getPackageName());
// view
    int resID = getResources().getIdentifier("my_resource", 
            "id", getPackageName());

// string
    int resID = getResources().getIdentifier("my_string", 
            "string", getPackageName());
Manthan Patel
źródło
0

Uważam, że ta klasa jest bardzo pomocna w zarządzaniu zasobami. Ma kilka zdefiniowanych metod radzenia sobie z wymiarami, kolorami, rysunkami i ciągami, takimi jak ten:

public static String getString(Context context, String stringId) {
    int sid = getStringId(context, stringId);
    if (sid > 0) {
        return context.getResources().getString(sid);
    } else {
        return "";
    }
}
Diego Malone
źródło
wikipedia mówi, że kotlin pojawił się po raz pierwszy w 2011 roku, czy możesz mi powiedzieć, jak to pytanie zostało zadane w 2010 roku i zadeklarowane dla Androida w 2019 roku, jak zadał pytanie kotlin na Androida w 2010 roku
Abhinav Chauhan
0

oprócz rozwiązania @lonkly

  1. zobacz odbicia i dostępność pola
  2. niepotrzebne zmienne

metoda:

/**
 * 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());
    }
}
ceph3us
źródło
wikipedia mówi, że kotlin pojawił się po raz pierwszy w 2011 roku, czy możesz mi powiedzieć, jak to pytanie zostało zadane w 2010 roku i zadeklarowane dla Androida w 2019 roku, jak zadał pytanie kotlin na Androida w 2010 roku
Abhinav Chauhan
0

W Kotlinie działa dla mnie dobrze:

val id = resources.getIdentifier("your_resource_name", "drawable", context?.getPackageName())

Jeśli zasób jest umieszczony w folderze mipmap, możesz użyć parametru „mipmap” zamiast „drawable”.

Jens van de Mötter
źródło