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
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
Antworten:
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$s
ist eine Zeichenfolge und%2$d
eine 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);
Beachten Sie, dass getString
es eine Überladung gibt, die die Zeichenfolge als Formatzeichenfolge verwendet:
String text = res.getString(R.string.welcome_messages, username, mailCount);
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 mailCount
Parameter 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.
Als ich das erste Mal sah %1$s
und %2$d
in 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]
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
Zeichenfolged
Dezimalzahlf
GleitkommazahlWir werden die folgende formatierte Zeichenfolge erstellen, in die die grauen Teile programmgesteuert eingefügt werden.
Meine Schwester
Mary
ist12
Jahre 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);
getString
weil 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.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.%1$s
mehrmals in der XML verwenden, wenn Sie ihn wiederholen möchten.%%
, um den tatsächlichen %
Charakter zu erhalten.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.
<!DOCTYPE... ]>
Teil in einer separaten Datei zu definieren und in mehrere Ressourcendateien aufzunehmen? Irgendein Trick, um dies zu erreichen?
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. :) :)
xliff
Tags um die Formatspezifizierer? Welchen zusätzlichen Wert bieten sie im Gegensatz zur alleinigen Verwendung der %s
und %d
-Spezifizierer?
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.
Sie sollten jedoch auch die Antwort von Elias Mårtenson auf die Android-Pluralbehandlung von „Null“ lesen . Es gibt ein Problem bei der Interpretation bestimmter Werte wie "Null".
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);
Sie können verwenden MessageFormat
:
<string name="customer_address">Wellcome: {0} {1}</string>
Im Java-Code:
String text = MessageFormat(R.string.customer_address).format("Name","Family");
API-Ebene 1:
https://developer.android.com/reference/java/text/MessageFormat.html
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
.
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>
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 )
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)));
Kotlin-Version der akzeptierten Antwort ...
val res = resources
val text = String.format(res.getString(R.string.welcome_messages), username, mailCount)
resources.getString(int, ... args)
Methode mit Argumenten anstelle von String.format
. Dieser Code enthält auch keine Kotlin-Details, außer dem val
Schlüsselwort. Siehe Antwort von msbodw001