Android: Comment puis-je obtenir une chaîne de ressources en utilisant son nom?


553

Je voudrais avoir 2 langues pour l'interface utilisateur et des valeurs de chaîne distinctes pour elles dans mon fichier de ressources 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>

Maintenant, je dois récupérer ces valeurs dynamiquement dans mon application:

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

Mon problème est que i = 0.

Pourquoi ça ne marche pas dans mon cas?


1
Êtes-vous certain que Central.lang est soit enou ru?
K-ballo

1
Plus d'informations sont nécessaires pour inspecter votre code. quel est l'état de chaque var avant d'obtenir i? Quoi qu'il en soit, vous devez utiliser la prise en charge de la localisation par défaut dans Android pour simplifier les choses.
Alin

Réponses:


1069

Le lien auquel vous faites référence semble fonctionner avec des chaînes générées lors de l'exécution. Les chaînes de strings.xml ne sont pas créées au moment de l'exécution. Vous pouvez les obtenir via

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

getResources()est une méthode de la Contextclasse. Si vous êtes dans un Activityou unService (qui étendent le contexte), vous pouvez l'utiliser comme dans cet extrait.

Notez également que toute la dépendance linguistique peut être prise en charge par le cadre Android . Créez simplement des dossiers différents pour chaque langue. Si l'anglais est votre langue par défaut, insérez simplement les chaînes anglaises res/values/strings.xml. Créez ensuite un nouveau dossier values-ruet placez les chaînes russes avec des noms identiques dans res/values-ru/strings.xml. À partir de ce moment, Android sélectionne le bon en fonction des paramètres régionaux de l'appareil pour vous, soit lorsque vous appelez, soit lorsque vous getString()référencez des chaînes en XML via @string/mystring. Ceux de res/values/strings.xmlsont ceux de secours, si vous n'avez pas de dossier couvrant les paramètres régionaux des utilisateurs, celui-ci sera utilisé comme valeurs par défaut.

Voir Localisation et fourniture de ressources pour plus d'informations.


23
Si vous êtes dans un android.support.v4.app.Fragment, vous pouvez simplement appeler getString(R.string.mystring)directement.
JaKXz

3
J'étais juste en train d'errer. Pourquoi est-il fait (par Google) d'une manière si compliquée? Obtenez d'abord l'ID numérique de mystring (à partir de l'objet R), puis obtenez la chaîne par cet ID? Et où réside la paire "ID-of-mystring => actualValue"? Pour autant que je sache, mystring => ID-of-mystring est dans R.java, mais c'est tout :)
Lukáš Řádek

2
assurez-vous que "R" est le R de votre projet et non le R. android par défaut
ralphgabb

2
C'est peut-être la réponse qui était nécessaire mais ce n'était pas celle qui était demandée! Pour accéder dynamiquement à une ressource de chaîne par nom, voir la réponse de @leonvian ... qui devrait être celle acceptée IMO
Chris Hatton

321

J'ai le même problème. Mais ce code ci-dessous fonctionne pour moi: Vérifiez si votre packageName est correct. Vous devez vous référer au package racine de votre application Android.

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

9
Dans le cas où quelqu'un a une bonne raison de le faire (par exemple, les fichiers de données contiennent une chaîne personnalisée qui décide quelle chaîne de ressource doit être affichée, ou si cette chaîne est extraite d'Internet) - alors je voudrais souligner que cette solution est la bonne. Corrigez particulièrement la partie où le type de ressource est stringou non strings. Parce que c'est logique (comme le reste d'Android). Donc, merci pour cela (et plus), @leonvian. :-)
Ivan Vučica

2
@Sameer pour obtenir un tableau par Strings, utilisez simplement: res.getStringArray (R.array.planets_array); Jetez un œil à ce lien officiel: developer.android.com/guide/topics/resources/…
leonvian

3
Cool. Pour se débarrasser d'une déclaration de méthode distincte, cela peut être "simplifié" de la manière suivante String someStringFromXML = getString(getResources().getIdentifier("some_string_name", "string", getPackageName()));:.
Neurotransmetteur

80

Pas seulement des activités:

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

cela a très bien fonctionné merci
Mosa

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

26

J'ajouterais quelque chose à la solution de leonvian, donc si par hasard la chaîne n'est pas trouvée parmi les ressources (valeur de retour 0, ce n'est pas un code de ressource valide), la fonction peut retourner quelque chose:

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

Meilleure approche

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

Fonctionnera partout (Utils, Models aussi).

J'ai lu toutes les réponses, toutes les réponses peuvent faire votre travail.

  • Vous pouvez utiliser getString(R.string.some_string_id)à la fois Activityou Fragment.
  • Vous pouvez utiliser Context.getString(R.string.some_string_id)là où vous n'avez pas d'accès direct à la getString()méthode. Comme Dialog.

Problème

Lorsque vous n'y avez pas Contextaccès , comme une méthode dans votre Utilclasse.

Supposons la méthode ci-dessous sans contexte.

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

Vous allez maintenant passer Contextcomme paramètre dans cette méthode et utilisergetString().

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

Ce que je fais c'est

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

Quelle? Il est très simple à utiliser n'importe où dans votre application!

Voici donc une solution par laquelle vous pouvez accéder aux ressources de n'importe où comme 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;
    }

}

Ajoutez un champ de nom à votre manifest.xml <applicationbalise.

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

Vous êtes maintenant prêt à partir. Utilisez App.getAppResources().getString(R.string.some_id)n'importe où dans l'application.


+1 solution simple et propre. Remarquez une mauvaise orthographe getResourses, getResourcescela entraînerait un remplacement. Le motif singleton semble également inutile, peut-être pourrait être ignoré. Des problèmes de fuite de mémoire avec cette solution?
Xarvalus

@Xarvalus Est-ce que cela fait fuir la mémoire?
Khemraj

dans mon application tout va bien :) je me demandais juste si quelqu'un avait un problème avec ça. Je le ferai savoir si je rencontre un écueil.
Xarvalus

1
@Xarvalus Memory Leak se produit généralement à l'endroit où une variable est utilisée, même la classe parente est détruite. Comme dans les activités, les fragments. Je ne pense pas que cela se produira dans ce cas.
Khemraj


14

Un moyen simple d'obtenir une chaîne de ressource d'une chaîne dans une TextView. Ici resourceName est le nom de la ressource

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

7

Si vous n'avez pas de référence d'activité, vous pouvez utiliser votre contexte de cette manière:

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

4

Il existe également un ensemble de chaînes Android prédéfinies telles que "Ok", "Annuler" et bien d'autres - vous n'avez donc pas à tout déclarer. Ils sont disponibles simplement par:

getString(android.R.string.ok)

(Dans ce cas, chaîne "Ok"). BTW, il existe également d'autres ressources Android comme par exemple des images d'icônes, etc.


2

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

moyen facile


1

Vous pouvez essayer ceci dans une activité:

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

Dans d'autres situations comme des fragments, ... utilisez

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

0

Pour être sûr, vous devez ajouter: mContext.getResources (). GetString (R.string.your_string);

mContext peut être: contexte dans onAttach () de Fragment ou this of Activity.


0

Si vous ne le souhaitez pas dans une activité ou un réseau de fragmentation, alors:

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

Si vous souhaitez l'obtenir à partir d'une classe en dehors de l'activité ou d'un fragment où vous n'avez pas le contexte d'activité, utilisez le contexte d'application:

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

0
R.string.<string_name>

Utilisez cette ligne directement dans votre fichier java. Rester simple.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.