Android, dostajesz identyfikator zasobu z string?

Muszę przekazać identyfikator zasobu do metody na jednej z moich klas. Musi używać zarówno identyfikatora, na który wskazuje Referencja, jak i łańcucha znaków. Jak najlepiej to osiągnąć?

Na przykład:

R.drawable.icon

Muszę uzyskać integer ID tego, ale potrzebuję również dostępu do łańcucha "icon".

Byłoby lepiej, gdybym tylko musiał przekazać do metody łańcuch "icon".

Author: Azhar, 2010-12-13

14 answers

@EboMike: nie wiedziałem, że Resources.getIdentifier() istnieje.

W moich projektach wykorzystałem do tego następujący kod:

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;
    } 
}

Zostanie użyty w ten sposób do uzyskania wartości R.drawable.icon resource integer value

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

Właśnie znalazłem wpis na blogu mówiący, że Resources.getIdentifier() jest wolniejszy niż używanie reflection, tak jak ja. Zobacz.

 175
Author: Macarse,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-12 03:13:24

Możesz użyć tej funkcji, aby uzyskać identyfikator zasobu.

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

Więc jeśli chcesz uzyskać dla drawable wywołaj funkcję w ten sposób

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

I dla string można to tak nazwać

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

Przeczytaj to

 84
Author: Azhar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-26 16:24:11

jest to oparte na odpowiedzi @Macarse.

Użyj tego, aby uzyskać identyfikator zasobów w szybszy i bardziej przyjazny dla kodu sposób.

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);
    }
}

Przykład:

getId("icon", R.drawable.class);
 38
Author: Daniel De León,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-25 15:16:08

Jak uzyskać aplikację identyfikator zasobu z nazwy zasobu jest dość powszechnym i dobrze odpowiedzialnym pytaniem.

Jak uzyskać natywny identyfikator zasobów Androida z nazwy zasobu jest mniej dobrze odpowiedział. Oto moje rozwiązanie, aby uzyskać zasób rysowalny na Androida według nazwy zasobu:

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);
    }
}

Metoda może być modyfikowana w celu uzyskania dostępu do innych typów zasobów.

 30
Author: Martin Pearman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-06 17:08:33

Jeśli potrzebujesz sparować łańcuch i int, to co powiesz na 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);
}
 12
Author: Peter Knego,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-14 21:08:16

Możesz użyć Resources.getIdentifier(), chociaż musisz użyć formatu dla swojego ciągu znaków, tak jak używasz go w plikach XML, tj. package:drawable/icon.

 9
Author: EboMike,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-13 09:58:45

Tak mi się podobało, to mi działa:

    imageView.setImageResource(context.getResources().
         getIdentifier("drawable/apple", null, context.getPackageName()));
 8
Author: Sarvar Nishonboev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-26 13:49:08
Simple method to get resource ID:

public int getDrawableName(Context ctx,String str){
    return ctx.getResources().getIdentifier(str,"drawable",ctx.getPackageName());
}
 8
Author: Ivan Vovk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-08-22 10:39:46

Prosty sposób na uzyskanie identyfikatora zasobu z łańcucha znaków. Tutaj resourceName jest nazwą zasobu ImageView w folderze drawable, 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);
 6
Author: Muhammad Adil,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-16 15:37:38

Ponieważ powiedziałeś, że chcesz przekazać tylko jeden parametr i nie wydaje się, który ma znaczenie, możesz przekazać identyfikator zasobu, a następnie znaleźć nazwę łańcucha dla niego, tak:

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

To może być najbardziej efektywny sposób uzyskania obu wartości. Nie musisz zadzierać ze znalezieniem tylko części "ikony" z dłuższego Sznurka.

 4
Author: Steve Waring,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-02 07:32:48

W Twoim res / layout / my_image_layout.xml

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

Aby pobrać ImageView według wartości @ + id, w kodzie Javy zrób to:

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);  
 2
Author: Gene,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-03 05:25:31

Podejście do Kotlina

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
            }
        }

Użycie:

val resId = R.drawable::class.java.getId("icon")
 2
Author: Arsenius,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-04-02 02:08:55

W MonoDroid / Xamarin.Android można zrobić:

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

Ale ponieważ GetIdentifier nie jest zalecane w Androidzie - możesz użyć odbicia w ten sposób:

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

Gdzie proponuję umieścić try / catch lub zweryfikować struny, które przechodzisz.

 1
Author: Daniele D.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-27 17:03:20

Aby uzyskać Drawable id z String resource name używam tego kodu:

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;
    }
}
 1
Author: bitvale,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-29 10:50:20