AndroidでString.xmlに文字列を動的に追加することは可能ですか?


495

string.xml実行時に値を割り当てることができるプレースホルダーを文字列値に含めることは可能ですか?

例:

いくつかの文字列PLACEHOLDER1いくつかの文字列



@HarishGyananiいいえ、これは古いので、代わりにこれにマージする必要があります
Danh

回答:


1035

書式とスタイル

はい、文字列リソースから以下を参照してください:書式設定とスタイル設定

を使用して文字列をフォーマットする必要がある場合String.format(String, Object...)は、文字列リソースにフォーマット引数を配置することで実行できます。たとえば、次のリソースの場合:

<string name="welcome_messages">Hello, %1$s! You have %2$d new messages.</string>

この例では、フォーマット文字列には2つの引数%1$sがあります:は文字列と%2$d10進数です。次のように、アプリケーションからの引数を使用して文字列をフォーマットできます。

Resources res = getResources();
String text = String.format(res.getString(R.string.welcome_messages), username, mailCount);

基本的な使い方

getStringは、文字列をフォーマット文字列として使用するオーバーロードがあることに注意してください。

String text = res.getString(R.string.welcome_messages, username, mailCount);

複数形

複数を処理する必要がある場合は、これを使用します。

<plurals name="welcome_messages">
    <item quantity="one">Hello, %1$s! You have a new message.</item>
    <item quantity="other">Hello, %1$s! You have %2$d new messages.</item>
</plurals>

最初のmailCountパラメーターは、使用する形式(単数または複数)を決定するために使用されます。他のパラメーターは、代わりに使用します。

Resources res = getResources();
String text = res.getQuantityString(R.plurals.welcome_messages, mailCount, username, mailCount);

詳細については、文字列リソース:複数形を参照してください。


61
最初のコードサンプルのString.format呼び出しは実際には不要です。Resources.getString()はフォーマットをサポートしています。次を参照してください:developer.android.com/reference/android/content/res/…、java.lang.Object ...)
Arnaud

16
String.xmlのPluralsの場合、R.string.welcome_messagesではなくR.plurals.welcome_messagesとしてIDを指定する必要があります
om252345

最後のアイテム文字列だけを返す複数のもの...どのように追加文字列を取得できるかについてのアイデア
CoDe 2014年

1
このメソッドを使用して文字列をフォーマットすると、ハイパーリンクなど、XML文字列テキストに含まれている可能性のあるメタタグがすべて削除されます
Jonathan

4
文字列は%1 $ s、10進数は%2 $ d、整数は何を表していますか?%1、%2の意味は何ですか?これはパラメータのカウントですか?.3番目のパラメータが必要な場合%3に言及していますか?
reegan29

260

補足回答

いつ最初ののこぎり%1$s%2$d受け入れ答えに、それは意味を成しません。ここでもう少し説明します。

それらはフォーマット指定子と呼ばれます。xml文字列では、次の形式になります。

%[parameter_index$][format_type] 
  • :パーセント記号は、フォーマット指定子の始まりを示します。
  • パラメータインデックス:これは、ドル記号が後に続く数値です。あなたは、文字列に挿入したい3つのパラメータを持っていた場合、それらが呼び出されることになる1$2$3$。リソース文字列にそれらを配置する順序は重要ではなく、パラメーターを指定する順序だけが重要です。
  • フォーマットタイプ:物事をフォーマットする方法はたくさんあります(ドキュメントを参照)。一般的なものは次のとおりです。

    • s ストリング
    • d 10進整数
    • f 浮動小数点数

次のフォーマットされた文字列を作成し、灰色の部分をプログラムで挿入します。

私の妹Mary12歳です。

string.xml

<string name="my_xml_string">My sister %1$s is %2$d years old.</string>

MyActivity.java

String myString = "Mary";
int myInt = 12;
String formatted = getString(R.string.my_xml_string, myString, myInt);

ノート

  • getString活動中だったので使用できました。あなたは使用することができcontext.getResources().getString(...)、それが利用できない場合。
  • String.format() 文字列もフォーマットします。
  • 用語は、その順序で使用する必要はありません。つまり、前に来ることができます。これは、異なる語順を使用する言語向けにアプリを国際化する場合に役立ちます。1$2$2$1$
  • %1$s繰り返したい場合は、xmlで複数回などの形式指定子を使用できます。
  • %%実際の%文字を取得するために使用します。
  • 詳細については、次の役立つチュートリアルをご覧ください。AndroidSDKクイックヒント:リソース文字列のフォーマット

125

Javaコードを使用せずに実際のstrings.xmlファイルのパラメーターを使用する場合:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE resources [
  <!ENTITY appname "WhereDat">
  <!ENTITY author "Oded">
]>

<resources>
    <string name="app_name">&appname;</string>
    <string name="description">The &appname; app was created by &author;</string>
</resources>

これはリソースファイル全体では機能しません。つまり、変数はそれらを必要とする各XMLファイルにコピーする必要があります。


<![CDATA [&param;
Hermann Poilpre

2
別の<!DOCTYPE... ]>ファイルでパーツを定義し、それを複数のリソースファイルに含める方法はありますか?これを達成するためのトリックはありますか?
prom85 2018年

18

同じものを探していて、最終的に次の非常に簡単な解決策を見つけました。最良:そのまま使用できます。
1.文字列リソースを変更します。

<string name="welcome_messages">Hello, <xliff:g name="name">%s</xliff:g>! You have 
<xliff:g name="count">%d</xliff:g> new messages.</string>

2.文字列置換を使用します。

c.getString(R.string.welcome_messages,name,count);

ここで、cはコンテキスト、nameは文字列変数で、int変数をカウントします

含める必要があります

<resources xmlns:xliff="http://schemas.android.com/apk/res-auto">

res / strings.xml内。私のために働く。:)


2
xliffフォーマット指定子を囲むタグのポイントは何ですか?%s%d指定子を単独で使用するのとは対照的に、追加の値は何ですか?
Richard Le Mesurier

xliffタグの「name」属性は、そこで何が置換されるかについて翻訳者にヒントを与えるための単なる方法です。「%s」の意味を推測するのは簡単ではない場合があります。
hugomg

3

Kotlinでは、次のように文字列値を設定するだけです。

<string name="song_number_and_title">"%1$d ~ %2$s"</string>

レイアウトにテキストビューを作成します。

<TextView android:id="@+id/song_number_and_title"/>

次に、Ankoを使用している場合は、コードでこれを実行します。

val song = database.use { // get your song from the database }
song_number_and_title.setText(resources.getString(R.string.song_number_and_title, song.number, song.title))  

アプリケーションコンテキストからリソースを取得する必要がある場合があります。


5
それはJavaの例とどう違うのですか?違いはありません
Janusz Hain


1

res / values / string.xml内

<resources>
    <string name="app_name">Hello World</string>
    <string name="my_application">Application name: %s, package name: %s</string>
</resources>

Javaコードで

String[] args = new String[2];
args[0] = context.getString(R.string.app_name);
args[1] = context.getPackageName();
String textMessage = context.getString(R.string.my_application,(Object[]) args);


1

パーセント(%)を書きたい場合は、複製します。

<string name="percent">%1$d%%</string>

label.text = getString(R.string.percent, 75) // Output: 75%.

単純%1$d%に書くと、エラーが発生しますFormat string 'percent' is not a valid format string so it should not be passed to String.format


0

はい!Java / Kotlinコードを記述せずに作成できます。ビルド時に作成するこの小さなライブラリを使用してXMLのみを作成します。これにより、アプリは影響を受けません。https//github.com/LikeTheSalad/android -string-reference

使用法

あなたの文字列:

<resources>
    <string name="app_name">My App Name</string>
    <string name="template_welcome_message">Welcome to ${app_name}</string>
</resources>

ビルド後に生成される文字列:

<!--resolved.xml-->
<resources>
    <string name="welcome_message">Welcome to My App Name</string>
</resources>

0

この問題に対するKotlinの直接的な解決策:

strings.xml

<string name="customer_message">Hello, %1$s!\nYou have %2$d Products in your cart.</string>

kotlinActivityORFragmentFile.kt:

val username = "Andrew"
val products = 1000
val text: String = String.format(
      resources.getString(R.string.customer_message), username, products )

0

文字列ファイルでこれを使用します

<string name="redeem_point"> You currently have %s points(%s points = 1 %s)</string>

そしてあなたのコードではそれに応じて使用します

coinsTextTV.setText(String.format(getContext().getString(R.string.redeem_point), rewardPoints.getReward_points()
                        , rewardPoints.getConversion_rate(), getString(R.string.rs)));

-1

受け入れられた回答のKotlinバージョン...

val res = resources
val text = String.format(res.getString(R.string.welcome_messages), username, mailCount)

3
より正しい方法は、のresources.getString(int, ... args)代わりに引数付きのメソッドを使用することですString.format。このコードには、valキーワード以外のkotlin固有の情報もありません。msbodw001の回答を見る
dant3
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.