안드로이드, 문자열에서 리소스 ID를 얻습니까?


158

내 클래스 중 하나의 메소드에 자원 ID를 전달해야합니다. 참조가 가리키는 id와 문자열이 필요합니다. 이것을 어떻게 가장 잘해야합니까?

예를 들면 다음과 같습니다.

R.drawable.icon

정수 ID를 가져와야하지만 "icon"문자열에 액세스해야합니다.

메소드에 전달해야하는 모든 것이 "아이콘"문자열이면 바람직합니다.


비슷한 방법으로 내부 저장소에 저장된 파일의 getId를 얻을 수 있습니까? 문제가 발생하여 갤러리 대신 위치 대신 ID 배열을 제공해야합니다 (어댑터라고 생각했습니다) .. thanks
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()두 번의 반사 조회를 수행해야합니다. 위의 예에서 getIdentifier()reflection을 사용하여 get을 얻은 Drawable.class다음 다른 반사 조회를 사용하여 자원 ID를 가져옵니다. 그것은 속도 차이를 설명 할 것입니다. 즉, 특히 빠르지 않으므로 실제로 캐시해야합니다 (특히 루프 또는 행의 경우 ListView). 그리고 리플렉션 접근법의 큰 문제는 향후 릴리스에서 변경 될 수있는 Android의 내부에 대해 가정한다는 것입니다.
CommonsWare

1
@CommonsWare : 맞습니다. 나는 안드로이드가 어떻게 구현되었는지 확인하고 있었고 결국 네이티브 호출이되었습니다. gitorious.org/android-eeepc/base/blobs/… => gitorious.org/android-eeepc/base/blobs/…
Macarse

3
대신 ID가있는 정수 배열을 사용합니다. ID에 문자열을 사용하는 것이 올바른 접근법처럼 들리지 않습니다.
EboMike

9
context매개 변수입니까?
Rudey

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

따라서 이와 같이 drawable call 함수 를 얻으려면

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

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

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

고마워 남자 정말 도움이되었습니다. 나는 많이 검색하고 그것을 얻지 못했습니다. 귀하의 답변을 확인한 결과 두 번째 매개 변수 getIdentifierid입니다. 이것은 안드로이드 개발 사이트에서도 언급되지 않았습니다. 그 정보는 어디서 얻었습니까?
Prakash GPz

4

하나의 매개 변수 만 전달하고 싶다고 말했지만 어느 것이 중요하지 않은 것 같으므로 리소스 식별자를 전달한 다음 문자열 이름을 찾을 수 있습니다.

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

이것은 두 값을 얻는 가장 효율적인 방법 일 수 있습니다. 더 긴 문자열에서 "아이콘"부분을 찾는 것을 망설 일 필요가 없습니다.


2

res / layout / my_image_layout.xml에서

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

@ + id 값으로 ImageView를 가져 오려면 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

코 틀린 접근

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

여기서 시도 / 캐치를 넣거나 전달하는 문자열을 확인하는 것이 좋습니다.


1

String 리소스 이름에서 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.