Android、文字列からリソースIDを取得しますか?


158

いずれかのクラスのメソッドにリソースIDを渡す必要があります。参照が指すIDと文字列の両方を使用する必要があります。これを最もよく達成するにはどうすればよいですか?

例えば:

R.drawable.icon

これの整数IDを取得する必要がありますが、文字列 "icon"へのアクセスも必要です。

メソッドに渡す必要があるのは「アイコン」文字列だけの場合が望ましいでしょう。


内部ストレージに保存されたファイルのgetIdと同様の方法で可能ですか?私はギャラリーにロケーションではなくIDの配列を提供する必要があるため、問題があります(アダプターだと思います)。おかげで
Ewoks

@Ewoks:内部ストレージにIDはありません。それらは単なる画像であり、それらを一連のImageオブジェクトにロードして渡す必要がある場合は、新しい質問を開始することもできます。
Hamid

回答:


171

@EboMike:私はそれがResources.getIdentifier()存在することを知りませんでした。

私のプロジェクトでは、次のコードを使用してそれを行いました。

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

R.drawable.iconリソース整数値の値を取得するためにこのように使用されます

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

Resources.getIdentifier()リフレクションを使用するよりも遅いというブログ投稿を見つけました。ご覧ください


8
@Macarse:現在、getIdentifier()2つの反射ルックアップを実行する必要があります。上記の例でgetIdentifier()は、リフレクションを使用してを取得しDrawable.class、次に別のリフレクションルックアップを使用してリソースIDを取得します。それは速度の違いを説明します。そうは言っても、どちらも特に高速ではないため、実際にキャッシュする必要があります(特にループで使用する場合、またはの行に使用する場合ListView)。また、リフレクションアプローチの大きな問題は、Androidの内部について、将来のリリースで変更される可能性があることを想定していることです。
CommonsWare 2010

1
@CommonsWare:そうです。私はandroidがどのように実装されているかを確認していましたが、結果としてネイティブコールになりました。gitorious.org/android-eeepc/base/blobs/... => gitorious.org/android-eeepc/base/blobs/...
Macarse

3
代わりにIDの整数配列を使用します。IDに文字列を使用することは、正しいアプローチのように聞こえません。
EboMike、

9
なぜcontextパラメーターなのか?
Rudey 2013

14
呼び出しはgetId( "icon"、R.drawable.class);である必要があります。getResId( "icon"、context、Drawable.class);ではありません。
Smeet

80

この関数を使用して、リソース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;
    } 
}

したがって、このようなドローアブル呼び出し関数を取得したい場合

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

文字列の場合は、次のように呼び出すことができます

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

これを読む


11
単純に別の関数を呼び出して、可能性のある例外を「処理」する関数を作成する意味は何ですか getResources()。getIdentifier()を直接呼び出します。
Ricardo Meneghin Filho

37

これは@Macarseの回答に基づいています。

これを使用して、リソースIDをより高速でコードに適した方法で取得します。

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

例:

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

30

リソース名からアプリケーションリソースID を取得する方法は、よくあるよくある質問です。

リソース名からネイティブのAndroidリソースID を取得する方法はあまりよく答えられていません。以下は、リソース名でAndroidドローアブルリソースを取得するための私の解決策です。

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

このメソッドは、他のタイプのリソースにアクセスするように変更できます。


現在.getResources()。getDrawableは非推奨 if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP){ return mContext.getDrawable(resourceId); } else { return mContext.getResources().getDrawable(resourceId); }
Evilripper

11

文字列とintをペアにする必要がある場合、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);
}

9

を使用できますがResources.getIdentifier()、XMLファイルで使用する文字列の形式を使用する必要がありますpackage:drawable/icon


以下の私の答えはこれの逆です。リソースIDを渡し、それを使用getResourceEntryName(id)して文字列名を検索します。長いテキストから「アイコン」を見つけるのにごちゃごちゃする必要はありません。
Steve Waring 2014

8

私はこれを好きでした、それは私のために働いています:

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

7
Simple method to get resource ID:

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

1
あなたの答えにいくつかのより多くの情報を与えるだけなら、より良いでしょう。
xMRi 2017年

6

文字列からリソースIDを取得する簡単な方法。ここで、resourceNameは、XMLファイルにも含まれているドローアブルフォルダー内のリソースImageViewの名前です。

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

ありがとう、それは本当に役に立ちました。あなたの答えを見て、の2番目のパラメーターはでgetIdentifierなければならないことがわかりましたid。これは、Android開発サイトでも言及されていません。どこでその情報を入手しましたか?
Prakash GPz 2016年

4

1つのパラメーターのみを渡したいと言っていて、どちらでも問題がないように思われたので、リソースIDを渡して、その文字列名を見つけることができました。

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

これは、両方の値を取得する最も効率的な方法かもしれません。長い文字列から "アイコン"の部分だけを探す必要はありません。


2

res / layout / my_image_layout.xml

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

ImageViewを@ + id値で取得するには、Javaコード内で次のようにします。

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

Kotlinのアプローチ

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

使用法:

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

1

MonoDroid / Xamarin.Androidでできること:

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

ただし、GetIdentifierはAndroidでは推奨されないため、次のようにReflectionを使用できます。

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

ここで、try / catchを配置するか、渡す文字列を確認することをお勧めします。


1

文字列リソース名からDrawable idを取得するために、私は次のコードを使用しています。

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;
    }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.