2011-09-21 9 views
385

chciałbym mieć 2 języków dla interfejsu użytkownika i osobny ciąg wartości dla nich w moim pliku zasobów res\values\strings.xml:Android: w jaki sposób uzyskać ciąg od zasobów przy użyciu jego nazwy?

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

teraz muszę odzyskać te wartości dynamicznie w moim aplikacja:

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

Mój problem polega na tym, że i = 0 .

Dlaczego to nie działa w moim przypadku?

+1

Czy jesteś pewien, że Central.lang to 'en' lub' ru'? –

+0

Potrzebujesz więcej informacji, aby sprawdzić kod. jaki jest stan każdego var przed uzyskaniem i? W każdym razie powinieneś użyć domyślnej obsługi lokalizacji w systemie Android, aby wszystko było proste. – Alin

Odpowiedz

786

Link, do którego się odwołuje, działa z ciągami generowanymi w środowisku wykonawczym. Łańcuchy z pliku strings.xml nie są tworzone w środowisku wykonawczym. Można je dostać poprzez

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

getResources() jest metodą klasy Context. Jeśli znajdujesz się wewnątrz Activity lub Service (które rozszerzają Kontekst), możesz go użyć jak w tym fragmencie.

Również zauważa, że ​​zależność od całego języka może być pod kontrolą systemu Android:. Po prostu utwórz różne foldery dla każdego języka. Jeśli angielski jest Twoim domyślnym językiem, po prostu wpisz angielskie ciągi znaków w res/values/strings.xml. Następnie utwórz nowy folder values-ru i umieść rosyjski ciąg znaków o identycznych nazwach w res/values-ru/strings.xml. Od tego momentu na Androidzie wybieramy właściwą w zależności od ustawienia urządzenia dla ciebie, albo gdy zadzwonisz pod numer getString() lub gdy powiążesz łańcuchy w XML przez @string/mystring. Te z wersji res/values/strings.xml są rezerwowymi, jeśli nie masz folderu obejmującego ustawienia regionalne użytkownika, ten będzie używany jako wartości domyślne.

Aby uzyskać więcej informacji, zobacz temat Localization i Providing Resources.

+7

Jeśli korzystasz z 'android.support.v4.app.Fragment', możesz po prostu wywołać' getString (R.string.mystring) 'bezpośrednio. – JaKXz

+1

Po prostu wodowałem. Dlaczego jest to zrobione (przez Google) w tak skomplikowany sposób? Najpierw zdobądź numeryczny identyfikator mistring (z obiektu R), a następnie pobierz ciąg znaków według tego identyfikatora? I gdzie właściwie znajduje się para "ID-of-mystring => actualValue"? O ile mi wiadomo, mystring => ID-of-mystring jest w R.java, ale to jest to :) –

+0

upewnij się, że "R" to Twój projekt R nie jest domyślnym Androidem R. – ralphgabb

247

Mam ten sam problem. Ale poniższy kod działa dla mnie: Sprawdź, czy nazwa twojego pakietu jest prawidłowa. Musisz odwołać się do głównego pakietu aplikacji na Androida.

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

Jeśli ktoś ma ku temu dobry powód (na przykład pliki danych zawierają niestandardowy ciąg, który decyduje, który zasób ciąg powinien być wyświetlony, lub jeśli ten ciąg jest pobierany z Internetu) - wtedy chciałbym zaznaczyć, że to rozwiązanie jest poprawne. Szczególnie popraw część, w której typem zasobu jest 'string', a nie' string'. Ponieważ jest to logiczne (podobnie jak reszta systemu Android). Dzięki za to (i więcej), @leonvian. :-) –

+0

i jak czytać tablicę? – Sameer

+2

@ Sameer, aby uzyskać tablicę według Stringów, wystarczy użyć: res.getStringArray (R.array.planets_array); Zobacz ten oficjalny link: http://developer.android.com/guide/topics/resources/string-resource.html#StringArray – leonvian

25

chciałbym dodać coś do rozwiązania leonvian, więc jeśli przypadkiem ciąg nie zostanie znaleziony wśród zasobów (zwracanej wartości 0, że nie jest to prawidłowy kod zasobów), funkcja może zwrócić coś:

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

Prosty sposób na uzyskanie identyfikatora zasobu z łańcucha. Tutaj nazwa_źródła to nazwa 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); 
50

nie tylko z działań:

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

Jeśli nie mają aktywności referencyjnej, można korzystać z kontekstu, w ten sposób:

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

Istnieje również zestaw z predefiniowanych ciągów z Androidem takich jak "Ok", "Anuluj" i wiele innych - dzięki czemu nie musisz zadeklarować wszystkich. Są dostępne po prostu przez:

getString(android.R.string.ok) 

(W tym przypadku ciąg "OK"). BTW dostępne są również inne zasoby Androida, takie jak na przykład obrazy ikon itp.

Powiązane problemy