안드로이드 : 이름을 사용하여 리소스에서 문자열을 얻는 방법은 무엇입니까?


553

UI에 2 가지 언어를 사용하고 리소스 파일에 별도의 문자열 값을 지정하고 싶습니다 res\values\strings.xml.

<string name="tab_Books_en">Books</string>
<string name="tab_Quotes_en">Quotes</string>
<string name="tab_Questions_en">Questions</string>
<string name="tab_Notes_en">Notes</string>
<string name="tab_Bookmarks_en">Bookmarks</string>

<string name="tab_Books_ru">Книги</string>
<string name="tab_Quotes_ru">Цитаты</string>
<string name="tab_Questions_ru">Вопросы</string>
<string name="tab_Notes_ru">Заметки</string>
<string name="tab_Bookmarks_ru">Закладки</string>

이제 앱에서 이러한 값을 동적으로 검색해야합니다.

spec.setContent(R.id.tabPage1);
String pack = getPackageName();
String id = "tab_Books_" + Central.lang;
int i = Central.Res.getIdentifier(id, "string", pack);
String str = Central.Res.getString(i);

내 문제는 i = 0.

내 경우에는 왜 작동하지 않습니까?


1
Central.lang이 en또는 ru입니까?
K-ballo

1
코드를 검사하려면 더 많은 정보가 필요합니다. i를 받기 전에 각 var의 상태는 무엇입니까? 어쨌든, 당신은 일을 간단하게 유지하기 위해 안드로이드에서 기본 현지화 지원을 사용해야합니다.
Alin

답변:


1069

언급 한 링크는 런타임에 생성 된 문자열로 작동하는 것 같습니다. strings.xml의 문자열은 런타임에 작성되지 않습니다. 당신은 그들을 통해 얻을 수 있습니다

String mystring = getResources().getString(R.string.mystring);

getResources()Context클래스 의 방법입니다 . ( Activity또는 Service컨텍스트를 확장 하는) 내부에있는 경우이 코드 조각과 같이 사용할 수 있습니다.

또한 전체 언어 종속성은 android 프레임 워크에서 처리 할 수 ​​있습니다 . 언어마다 다른 폴더를 만들면됩니다. 영어가 기본 언어 인 경우 영어 문자열을에 넣으십시오 res/values/strings.xml. 그런 다음 새 폴더를 만들고 values-ru이름이 같은 러시아어 문자열을에 넣습니다 res/values-ru/strings.xml. 이 시점에서 안드로이드는 전화를 걸 getString()거나 XML을 통해 문자열을 참조 할 때 장치 로캘에 따라 올바른 것을 선택합니다 @string/mystring. 의 res/values/strings.xml폴더는 폴백 폴더이며, 사용자 로캘을 포함하는 폴더가 없으면이 폴더가 기본값으로 사용됩니다.

자세한 내용은 현지화리소스 제공 을 참조하십시오.


23
에 있다면 직접 android.support.v4.app.Fragment전화하면 getString(R.string.mystring)됩니다.
JaKXz

3
나는 방황했다. 왜 그렇게 복잡한 방식으로 (Google에서) 수행됩니까? 먼저 (R 객체에서) mystring의 숫자 ID를 얻은 다음 해당 ID로 문자열을 가져 옵니까? 그리고 "ID-of-mystring => actualValue"쌍이 실제로 어디에 있습니까? 내가 아는 한 mystring => ID-of-mystring은 R.java에 있지만, 그것이 바로 그것입니다 :)
Lukáš Řádek

2
"R"이 프로젝트의 R이 기본 Android R이 아닌지 확인하십시오.
ralphgabb

2
이것은 필요한 답변 일 수도 있지만 요청 된 답변이 아닙니다! 이름으로 문자열 리소스에 동적으로 액세스하려면 @leonvian의 답변을 참조하십시오. 이것은 승인 된 IMO 여야합니다.
Chris Hatton

321

나는 같은 문제를 가지고있다. 그러나 아래 코드는 저에게 효과적입니다. packageName이 올바른지 확인하십시오. Android 애플리케이션의 루트 패키지를 참조해야합니다.

private String getStringResourceByName(String aString) {
      String packageName = getPackageName();
      int resId = getResources().getIdentifier(aString, "string", packageName);
      return getString(resId);
    }

9
누군가이 작업을 수행 해야하는 이유가있는 경우 (예 : 데이터 파일에 표시 할 리소스 문자열을 결정하거나 인터넷 에서이 문자열을 가져 오는지를 결정하는 사용자 지정 문자열이 포함되어 있음)-그 점을 지적하고 싶습니다 이 솔루션이 맞습니다. 특히 자원 유형이 string아닌 부분을 ​​정정하십시오 strings. 논리적이기 때문에 (다른 안드로이드와 마찬가지로). 따라서 @leonvian에게 감사드립니다. :-)
Ivan Vučica

2
@ 문자열로 배열을 가져 오는 @Sameer는 다음을 사용하십시오. res.getStringArray (R.array.planets_array); 이 oficial 링크를 살펴보십시오 : developer.android.com/guide/topics/resources/…
leonvian

3
멋있는. 별도의 메소드 선언을 제거하기 위해 다음과 같이 "단순화"할 수 있습니다 String someStringFromXML = getString(getResources().getIdentifier("some_string_name", "string", getPackageName()));.
신경 전달 물질

80

활동에서만이 아님 :

    public static String getStringByIdName(Context context, String idName) {
        Resources res = context.getResources();
        return res.getString(res.getIdentifier(idName, "string", context.getPackageName()));
    }

감사합니다
Mosa

39
getResources().getString(getResources().getIdentifier("propertyName", "string", getPackageName()))

26

나는 leonvian의 솔루션에 무언가를 추가 할 것이므로 우연히 문자열이 리소스 중에서 발견되지 않으면 (반환 값 0, 유효한 리소스 코드는 아님) 함수는 무언가를 반환 할 수 있습니다 :

private String getStringResourceByName(String aString) {
    String packageName = getPackageName();
    int resId = getResources()
            .getIdentifier(aString, "string", packageName);
    if (resId == 0) {
        return aString;
    } else {
        return getString(resId);
    }
}

15

최고의 접근법

App.getRes().getString(R.string.some_id)

어디에서나 작동합니다 (유틸리티, 모델도).

모든 답변을 읽었으며 모든 답변을 통해 업무를 수행 할 수 있습니다.

  • 또는 getString(R.string.some_string_id)모두에 사용할 수 있습니다 .ActivityFragment
  • 메소드에 Context.getString(R.string.some_string_id)직접 액세스 할 수없는 곳에서 사용할 수 있습니다 getString(). 처럼 Dialog.

문제

당신이없는 Context액세스를 당신의 방법처럼 Util클래스입니다.

컨텍스트가없는 아래 메소드를 가정하십시오.

public void someMethod(){
    ...
    // can't use getResource() or getString() without Context.
}

이제이 Context방법에서 매개 변수로 전달 하고getString().

public void someMethod(Context context){
    ...
    context.getString(R.string.some_id);
}

내가하는 일은

public void someMethod(){
    ...
    App.getAppResources().getString(R.string.some_id)
}

뭐? 앱 어디에서나 사용하는 것은 매우 간단합니다!

다음은 어디에서나 리소스에 액세스 할 수 있는 솔루션Util class 입니다.

import android.app.Application;
import android.content.res.Resources;

public class App extends Application {
    private static Resources resources;

    @Override
    public void onCreate() {
        super.onCreate();

        resources = getResources();
    }

    public static Resources getAppResources() {
        return resources;
    }

}

manifest.xml <application태그에 이름 필드를 추가하십시오 .

<application
        android:name=".App"
        ...
        >
        ...
    </application>

이제 잘 가십시오. App.getAppResources().getString(R.string.some_id)앱의 어느 곳에서나 사용하십시오 .


+1 간단하고 깨끗한 솔루션. 맞춤법이 잘못 getResourses되면 getResources재정의가 발생합니다. 또한 싱글 톤 패턴은 불필요 해 보일 수 있습니다. 이 솔루션의 메모리 누수 문제가 있습니까?
Xarvalus

@Xarvalus 메모리 누수가 발생합니까?
Khemraj

내 응용 프로그램에서 모든 괜찮습니다 :) 누군가가 그것에 문제가 있는지 궁금합니다. 함정에 부딪 치면 알려 드리겠습니다.
Xarvalus

1
@Xarvalus 메모리 누수는 일반적으로 부모 클래스가 파괴 되더라도 변수가 사용되는 곳에서 발생합니다. 활동, 조각처럼. 나는이 경우에 일어날 것이라고 생각하지 않습니다.
Khemraj


14

리소스 문자열을 문자열에서 TextView로 가져 오는 간단한 방법. 여기 resourceName은 자원의 이름입니다

int resID = getResources().getIdentifier(resourceName, "string", getPackageName());
textview.setText(resID);

7

활동 참조가없는 경우 다음과 같은 방식으로 컨텍스트를 사용할 수 있습니다.

getContext().getString(R.string.your_string_name);

4

"Ok", "Cancel"등과 같은 미리 정의 된 Android 문자열 세트도 있으므로 모두 선언 할 필요가 없습니다. 다음과 같이 간단하게 사용할 수 있습니다.

getString(android.R.string.ok)

(이 경우 "Ok"문자열). BTW에는 아이콘 이미지 등과 같은 다른 Android 리소스도 있습니다.



1

당신은 활동에서 이것을 시도 할 수 있습니다 :

getResources().getString(R.string.your string name);

조각과 같은 다른 상황에서는 ... 사용

getContext().getResources().getString(R.string.your string name);

0

안전을 위해 다음을 추가해야합니다. mContext.getResources (). getString (R.string.your_string);

mContext는 Fragment의 onAttach () 또는 Activity의 context 일 수 있습니다.


0

액티비티 나 프 래그 넷에 넣고 싶지 않은 경우 :

getContext().getResources().getString(R.string.string_name);

활동 컨텍스트가없는 활동 또는 조각 외부의 클래스에서 가져 오려면 응용 프로그램 컨텍스트를 사용하십시오.

getApplicationContext().getResources().getString(R.string.string_name);

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.