web-dev-qa-db-fra.com

Changer la valeur de R.string par programmation

J'ai déclaré une chaîne dans mon fichier strings.xml et je l'ai utilisée dans mon activité sous la forme R.string.compose_title. (en lui donnant le titre i.e. setTitle (R.id.compose_title)). Maintenant, dans certains cas, je veux éditer la chaîne, puis l'utiliser pour définir le titre. Comment puis-je faire ceci ?

P.S. Je n'ai besoin de changer que la valeur d'une seule chaîne. Déclarer un nouveau fichier strings.xml pour chaque cas (variables en fonction de l'utilisateur) à l'aide de la localisation semble donc être peu efficace. 

22
atuljangra

Une chose que vous devez comprendre ici est que, lorsque vous fournissez des données en tant que ressource, elles ne peuvent pas être modifiées pendant la phase d’exécution. Par exemple, les éléments que vous pouvez dessiner dans votre dossier ne peuvent pas être modifiés au moment de l'exécution. Pour être précis, le dossier "res" ne peut pas être modifié par programme. 

Cela s'applique également à Strings.xml, dans le dossier "Values". Si du tout vous voulez une chaîne qui doit être modifiée au moment de l'exécution, créez une classe séparée et placez-les dans cette classe et accédez-y pendant l'exécution. C'est la meilleure solution que j'ai trouvée. 

41
Andro Selva

exemple comment:

comment? en changeant une référence de variable en une autre référence

usage: 

setRColor(pl.mylib.R.class,"endColor",pl.myapp.R.color.startColor);
// override app_name in lib R class  
setRString(pl.mylib.R.class,"app_name",pl.myapp.R.string.app_name);

méthodes de base: 

public static void setRColor(Class rClass, String rFieldName, Object newValue) {
    setR(rClass, "color", rFieldName, newValue);
}

public static void setRString(Class rClass, String rFieldName, Object newValue) {
    setR(rClass, "string", rFieldName, newValue);
}

// AsciiStrings.STRING_DOLAR = "$";
public static void setR(Class rClass, String innerClassName, String rFieldName, Object newValue) {
    setStatic(rClass.getName() + AsciiStrings.STRING_DOLAR  + innerClassName, rFieldName, newValue);
}

méthodes d'assistance:

public static boolean setStatic(String aClassName, String staticFieldName, Object toSet) {
    try {
        return setStatic(Class.forName(aClassName), staticFieldName, toSet);
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
        return false;
    }
}

public static boolean setStatic(Class<?> aClass, String staticFieldName, Object toSet) {
    try {
        Field declaredField = aClass.getDeclaredField(staticFieldName);
        declaredField.setAccessible(true);
        declaredField.set(null, toSet);
        return true;
    } catch (Exception e) {
        e.printStackTrace();
        return false;
    }
}

@ bradenV2 Mon application prend en charge de nombreuses langues, je voulais donc prendre un chaîne de mon strings.xml qui est actuellement utilisé et changer cela, et ensuite utiliser celui-là - atuljangra 12 mars 12 à 22:04

ps la solution ci-dessus est bonne par exemple lorsque vous voulez injecter des données dans lib/jar déjà compilé. Mais si vous voulez localiser des chaînes, créez simplement un dossier sous res par LANG CODE, comme values-CC où cc est un code lang (values-de, values-cs), etc. 

alors vous avez 2 choix:

  1. sélection de la langue dépend du système "intégré" - en fonction du périphérique sélectionné 
  2. via créer des ressources pour la configuration - vous décidez quel lang show 

comme ça:

configuration = new Configuration(resources.getConfiguration());
configuration.setLocale(targetLocale);
String localized = Context.createConfigurationContext(configuration)
    .getResources()
    .getString(resourceId);

 enter image description here

4
ceph3us

Je ne pense pas que vous puissiez personnaliser par programme la classeRtelle qu'elle est construite automatiquement par ADT. 

4
waqaslam

J'ai eu une situation comme celle-ci, où l'une de mes valeurs strings.xml avait un élément dynamique. J'ai configuré le fichier strings.xml avec un "texte de remplacement" (du type %%REPLACEMENT_EMAIL%%) et, lorsque je souhaitais utiliser cette chaîne par programmation, j'ai extrait la valeur de chaîne de la ressource et remplacé les occurrences de ce texte par la valeur dynamique ( par exemple saisie par l'utilisateur).

Pour être honnête, mon application n'a pas encore été localisée, mais j'essaie toujours de suivre les meilleures pratiques avec w.r.t. pas coder en dur les chaînes.

1
Rob I

Vous souhaitez peut-être "modifier" le fichier string.xml afin que, lorsque l'activité l'exige de nouveau, elle utilise la nouvelle valeur, par exemple pour conserver un nouveau titre dynamique après la rotation de l'écran. 

Tout d'abord, vous ne pouvez pas modifier la ressource. C'est déjà compilé. Vous ne pouvez pas modifier la classe R (pour quoi faire?), Tous ses attributs sont "finaux". 

Ainsi, pour l'exemple ci-dessus, vous pouvez utiliser onSaveInstanceState () et onRestoreInstanceState () pour les propriétés que vous souhaitez conserver.

0

Utilisez SharedPreferences au lieu d'une classe Java. Cela vous donnera plus de polyvalence si vous décidez de prendre valeurs de l’extérieur (web). Remplir une classe Java à l'exécution peut être inutile hors ligne. Dans le cas de SharedPreferences vous devez vous assurer qu'elles ne sont chargées qu'une seule fois, lors du premier démarrage de l'application, puis mises à jour uniquement par demande manuelle, car l'importation précédente sera utilisée.

myActivity.getSharedPreferences("com.example.imported",0)
.edit()
.putString("The news",getTheNews())
.apply();
0
Zon

À ma connaissance, vous ne pouvez pas modifier la valeur de la ressource (valeur de classe R) pendant l'exécution de l'application. pourquoi ne pas essayer de stocker sur la préférence partagée? Je vous recommande d'utiliser la préférence partagée

0
Thinesh