web-dev-qa-db-ja.com

R.stringの値をプログラムで変更する

Strings.xmlファイルで文字列を宣言し、それをアクティビティでR.string.compose_titleとして使用しています。 (タイトルとして設定、つまりsetTitle(R.id.compose_title))。場合によっては、文字列を編集し、それを使用してタイトルを設定します。これどうやってするの ?

追伸私は単一の文字列の値のみを変更する必要があるので、ローカライズを使用して各ケース(ユーザーに応じて変数です)ごとに新しいstrings.xmlを宣言するのは非効率的です。

24
atuljangra

ここで理解しなければならないことの1つは、リソースとしてデータを提供する場合、実行中にデータを変更できないことです。たとえば、DrawableフォルダにあるDrawableは、実行時に変更できません。正確には、「res」フォルダーをプログラムで変更することはできません。

これは、Strings.xml、つまり「Values」フォルダにも適用されます。実行時に変更する必要がある文字列が必要な場合は、別のクラスを作成し、このクラスに文字列を配置して実行時にアクセスします。これは私が見つけた最良の解決策です。

46
Andro Selva

howtoの例:

どうやって? 1つの変数参照を他の参照に変更することにより

使用法:

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

基本メソッド:

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

ヘルパーメソッド:

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私のアプリは多くの言語をサポートしているので、現在使用中のstrings.xmlから文字列を取得して変更し、それを使用したいです。atuljangra12年3月12日22時04分

ps上記のソリューションは、たとえば、すでにコンパイルされたlib/jarにデータを挿入する場合に適しています。ただし、文字列をローカライズする場合は、values-CCのようなLANG CODEごとにresの下にフォルダーを作成します。ccはlangコード(values-de、values-cs)等

次に、2つの選択肢があります。

  1. 「ビルドイン」システム依存言語選択-選択したデバイスに基づいて言語
  2. 構成用のリソースの作成を介して-どの言語を表示するかを決定します

このような:

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

enter image description here

4
ceph3us

[〜#〜] r [〜#〜]クラスはADTによって自動的に構築されるため、プログラムでカスタマイズできるとは思いません。

4
waqaslam

このような状況では、strings.xmlの値の1つに動的な部分が含まれていました。 「replacement text」(%%REPLACEMENT_EMAIL%%)、およびその文字列をプログラムで使用する場合、リソースの文字列値を取得し、その置換テキストのインスタンスを動的な値(たとえば、ユーザーによる入力)に置き換えました。

正直なところ、私のアプリはまだローカライズされていませんが、私はまだベストプラクティスw.r.tに従うことを試みています。文字列をハードコーディングしません。

1
Rob I

String.xmlを「変更」して、アクティビティで再び必要になったときに、たとえば画面の回転後に新しい動的タイトルを保持するなど、新しい値を使用する場合があります。

まず、リソースを変更することはできません。すでにコンパイルされています。 Rクラスを変更することはできません(何のためですか?)、その属性はすべて「最終」です。

したがって、上記の例では、onSaveInstanceState()およびonRestoreInstanceState()を使用して、表示を維持したいプロパティに使用できます。

0

Javaクラスの代わりに SharedPreferences を使用します。外部から値を取得する場合は、より汎用性が高くなります(ウェブ)。Java実行時のクラスはオフラインで役に立たない可能性があります。 SharedPreferences の場合、アプリの最初の起動時に一度だけ読み込まれるようにする必要があります。以前のインポートが使用されるため、手動の要求によってのみ更新されます。

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

私の知る限り、アプリの実行中にリソース値(Rクラス値)を変更することはできません。なぜ共有設定に保存しようとしないのですか?共有設定を使用することをお勧めします

0
Thinesh