Ist es möglich, String.xml in Android dynamisch hinzuzufügen?


495

Ist es möglich, Platzhalter in Zeichenfolgenwerten zu haben string.xml, denen zur Laufzeit Werte zugewiesen werden können?

Beispiel:

einige Zeichenfolge PLACEHOLDER1 einige weitere Zeichenfolge



@ HarishGyanani Nein, dieser ist älter, dass man stattdessen mit diesem zusammengeführt werden sollte
— Danh

Antworten:


1035

Formatierung und Styling

Ja, siehe Folgendes unter Zeichenfolgenressourcen: Formatieren und Stylen

Wenn Sie Ihre Zeichenfolgen mit formatieren müssen, String.format(String, Object...)können Sie dies tun, indem Sie Ihre Formatargumente in die Zeichenfolgenressource einfügen. Zum Beispiel mit der folgenden Ressource:

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

In diesem Beispiel hat die Formatzeichenfolge zwei Argumente: %1$sist eine Zeichenfolge und %2$deine Dezimalzahl. Sie können die Zeichenfolge mit Argumenten aus Ihrer Anwendung wie folgt formatieren:

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

Grundlegende Verwendung

Beachten Sie, dass getStringes eine Überladung gibt, die die Zeichenfolge als Formatzeichenfolge verwendet:

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

Pluralformen

Wenn Sie mit Pluralformen umgehen müssen, verwenden Sie Folgendes:

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

Der erste mailCountParameter wird verwendet, um zu entscheiden, welches Format verwendet werden soll (Einzel- oder Plural). Die anderen Parameter sind Ihre Ersetzungen:

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

Siehe String - Ressourcen: Plurale für weitere Details.


61
Der Aufruf von String.format im ersten Codebeispiel ist eigentlich nicht erforderlich. Resources.getString () unterstützt die Formatierung, siehe: developer.android.com/reference/android/content/res/… , java.lang.Object ...)
— Arnaud

16
Für Plurals in String.xml müssen Sie die ID als R.plurals.welcome_messages anstelle von R.string.welcome_messages angeben
— om252345

Plural Ding, das nur die letzte Elementzeichenfolge zurückgibt ... jede Idee, wie man eine Zeichenfolge anhängen kann.
— CoDe

1
Bei Verwendung dieser Methode zum Formatieren Ihrer Zeichenfolge wurden alle Meta-Tags entfernt, die Sie möglicherweise verwendet haben, z. B. Hyperlinks usw., die im XML-Zeichenfolgentext enthalten sein könnten
— Jonathan

4
String steht für% 1 $ s, Dezimalzahl für% 2 $ d und Integer steht für was? Was bedeutet% 1,% 2.Ist diese Parameterzählung? .wenn ich den dritten Parameter möchte, wird% 3 erwähnt?
— reegan29

260

Ergänzende Antwort

Als ich das erste Mal sah %1$sund %2$din der akzeptierten Antwort, machte es keinen Sinn. Hier ist eine weitere Erklärung.

Sie werden als Formatbezeichner bezeichnet. In der XML-Zeichenfolge haben sie die Form

%[parameter_index$][format_type] 
  • % : Das Prozentzeichen markiert den Beginn des Formatbezeichners.
  • Parameterindex : Dies ist eine Zahl, gefolgt von einem Dollarzeichen. Wenn Sie drei Parameter haben , die Sie in die String einfügen wollten, dann würden sie genannt werden 1$, 2$und 3$. Die Reihenfolge, in der Sie sie in die Ressourcenzeichenfolge einfügen, spielt keine Rolle, nur die Reihenfolge, in der Sie die Parameter angeben.
  • Formattyp : Es gibt viele Möglichkeiten, wie Sie Dinge formatieren können ( siehe Dokumentation ). Hier sind einige gebräuchliche:

    • s Zeichenfolge
    • d Dezimalzahl
    • f Gleitkommazahl

Beispiel

Wir werden die folgende formatierte Zeichenfolge erstellen, in die die grauen Teile programmgesteuert eingefügt werden.

Meine Schwester Maryist 12Jahre alt.

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

Anmerkungen

  • Ich konnte verwenden, getStringweil ich in einer Aktivität war. Sie können verwenden, context.getResources().getString(...)wenn es nicht verfügbar ist.
  • String.format() formatiert auch einen String.
  • Die Begriffe 1$und 2$müssen nicht in dieser Reihenfolge verwendet werden. Das heißt, 2$kann vorher kommen 1$. Dies ist nützlich, wenn Sie eine App für Sprachen internationalisieren, die eine andere Wortreihenfolge verwenden.
  • Sie können einen Formatbezeichner wie %1$smehrmals in der XML verwenden, wenn Sie ihn wiederholen möchten.
  • Verwenden Sie %%, um den tatsächlichen %Charakter zu erhalten.
  • Weitere Informationen finden Sie im folgenden hilfreichen Tutorial: Android SDK-Kurztipp: Formatieren von Ressourcenzeichenfolgen

125

Wenn Sie einen Parameter aus der eigentlichen Datei strings.xml verwenden möchten, ohne Java-Code zu verwenden:

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

Dies funktioniert nicht über Ressourcendateien hinweg, dh Variablen müssen in jede XML-Datei kopiert werden, die sie benötigt.


Das ist eine gute Antwort, außer wenn Sie einen Parameter in <! [CDATA [& param; ]]>
— Hermann Poilpre

2
Gibt es eine Möglichkeit, das <!DOCTYPE... ]>Teil in einer separaten Datei zu definieren und in mehrere Ressourcendateien aufzunehmen? Irgendein Trick, um dies zu erreichen?
— prom85

18

War auf der Suche nach dem gleichen und fand schließlich die folgende sehr einfache Lösung. Das Beste: Es funktioniert sofort.
1. Ändern Sie Ihre String-Ressource:

<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. Verwenden Sie die Zeichenfolgenersetzung:

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

Dabei ist c der Kontext, name eine Zeichenfolgenvariable und zählt Ihre int-Variable

Sie müssen einschließen

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

in Ihrer res / strings.xml. Funktioniert bei mir. :) :)


2
Was ist der Sinn der xliffTags um die Formatspezifizierer? Welchen zusätzlichen Wert bieten sie im Gegensatz zur alleinigen Verwendung der %sund %d-Spezifizierer?
— Richard Le Mesurier

Das Attribut "name" im xliff-Tag ist nur eine Möglichkeit, dem Übersetzer einen Hinweis darauf zu geben, was dort ersetzt wird. Manchmal ist es nicht leicht zu erraten, was "% s" bedeutet.
— Hugomg

3

In Kotlin müssen Sie Ihren String-Wert nur so einstellen:

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

Erstellen Sie eine Textansicht in Ihrem Layout:

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

Dann tun Sie dies in Ihrem Code, wenn Sie Anko verwenden:

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

Möglicherweise müssen Sie Ihre Ressourcen aus dem Anwendungskontext abrufen.


5
Wie unterscheidet sich das von Java-Beispielen? Ich sehe keinen Unterschied
— Janusz Hain


1

in res / values ​​/ string.xml

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

in Java-Code

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

Wenn Sie Prozent (%) schreiben möchten, duplizieren Sie es:

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

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

Wenn Sie einfach schreiben %1$d%, erhalten Sie die Fehlermeldung : Format string 'percent' is not a valid format string so it should not be passed to String.format.


0

Ja! Sie können dies tun, ohne Java / Kotlin-Code zu schreiben, sondern nur XML, indem Sie diese kleine Bibliothek verwenden, die ich erstellt habe. Dies geschieht zur Erstellungszeit, sodass Ihre App davon nicht betroffen ist: https://github.com/LikeTheSalad/android -string-Referenz

Verwendungszweck

Deine Saiten:

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

Die generierte Zeichenfolge nach dem Erstellen:

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

0

Eine direkte Kotlin-Lösung für das Problem:

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

Verwenden Sie dies in Ihrer String-Datei

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

Und in Ihrem Code entsprechend verwenden

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

-1

Kotlin-Version der akzeptierten Antwort ...

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

3
Richtiger ist die Verwendung einer resources.getString(int, ... args)Methode mit Argumenten anstelle von String.format. Dieser Code enthält auch keine Kotlin-Details, außer dem valSchlüsselwort. Siehe Antwort von msbodw001
— dant3
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.