I have some packages with a status.
in strings xml those status would be (translated to norwegian)
<string name="collectable">Kan hentes</string>
<string name="underway">Underveis</string>
<string name="transport_to_recipient">Leveres i dag</string>
<string name="returned">Sendt i retur</string>
<string name="archived">Utlevert</string>
<string name="sent">Sendt av deg</string>
<string name="unknown">Foreløpig ukjent</string>
so in my xml layout i want to do something like this:
android:text="#{`#strings/`+ parcelListItem.status.toString()}"
so the string names would match with the text. i am also using databinding for this to get parcelitem.status.
My problem is that it just prints out "#strings/transport_to_receipient", not the actual translation. Is there a way to do this in a smart way, or should i just probably make a method on it?
You need to get the by using something like this:
public String getStringByString(String key) {
String retString = key;
int id = getResource().getIdentifier(key, "string", getPackageName());
if (id != 0) {
retString = getString(id);
}
return retString;
}
So basically this will try to get the resource name from you strings.xml file. If it fails will return the key.
To access this string <string name="transport_to_recipient">Leveres i dag</string> you need to update your resource configuration just LIKE THIS.
Resources resources= context.getResources();
Configuration configuration = resources.getConfiguration();
DisplayMetrics metrics= resources.getDisplayMetrics();
configuration.setLocale(new Locale("nb")); //country code depend on your XML
resources.updateConfiguration(configuration,metrics);
nb is country code might be in your case it will be different.
You will country code on the side of string.xml file in Resource folder.
Ended up using this method based on the answer above:
public static int getStringResourceIdByName(Context context, String stringId) {
if (Utils.isNullOrBlank(stringId))
stringId = ParcelListItem.Status.unknown.toString();
return context.getResources().getIdentifier(stringId, "string", context.getPackageName());
}
and referred like this:
Utils.getStringResourceIdByName(context, parcelListItem.status.toString())
Related
So this works fine:
strFoo = "\u20B9" + strBar
But this doesn't
strFoo = R.string.rupee_symbol.toString() + strBar //.toString() is required
//R.string.rupee_symbol.toString() evaluates to some random number 2131755148... which I believe is a character array...
strings.xml
<string name="rupee_symbol">\u20B9 </string>
I can't figure out why it would behave like that, it looks like the same thing...!
You should not concatenate strings with string resources instead, you can use place holder:
<string name="rupee_symbol">\u20B9%s</string>
And use:
strFoo = resources.getString(R.string.rupee_symbol, strBar)
use getString(R.string.rupee_symbol) instead R.string.rupee_symbol.toString()
For example-
String strBar = String.valueOf(100);
String strFoo = getString(R.string.rupee_symbol)+strBar;
textView.setText( strFoo);
I have strings defined in the usual strings.xml Resource file like this:
<string name="hello_world"> HELLO</string>
Is it possible to define format strings such as the one below
result_str = String.format("Amount: %.2f for %d days ", var1, var2);
in the strings.xml resource file?
I tried escaping the special characters but its not working.
You do not need to use formatted="false" in your XML. You just need to use fully qualified string format markers - %[POSITION]$[TYPE] (where [POSITION] is the attribute position and [TYPE] is the variable type), rather than the short versions, for example %s or %d.
Quote from Android Docs: String Formatting and Styling:
<string name="welcome_messages">Hello, %1$s! You have %2$d new messages.</string>
In this example, the format string has two arguments: %1$s is a
string and %2$d is a decimal integer. You can format the string with
arguments from your application like this:
Resources res = getResources();
String text = res.getString(R.string.welcome_messages, username, mailCount);
You should add formatted="false" to your string resource
Here is an example
In your strings.xml :
<string name="all" formatted="false">Amount: %.2f%n for %d days</string>
In your code:
yourTextView.setText(String.format(getString(R.string.all), 3.12, 2));
Inside file strings.xml define a String resource like this:
<string name="string_to_format">Amount: %1$f for %2$d days%3$s</string>
Inside your code (assume it inherits from Context) simply do the following:
String formattedString = getString(R.string.string_to_format, floatVar, decimalVar, stringVar);
(In comparison to the answer from LocalPCGuy or Giovanny Farto M. the String.format method is not needed.)
Quote from Android Docs:
If you need to format your strings using String.format(String,
Object...), then you can do so by putting your format arguments in the
string resource. For example, with the following resource:
<string name="welcome_messages">Hello, %1$s! You have %2$d new messages.</string>
In this example, the format string has two arguments: %1$s is a string
and %2$d is a decimal number. You can format the string with arguments
from your application like this:
Resources res = getResources();
String text = String.format(res.getString(R.string.welcome_messages), username, mailCount);
For me it worked like that in Kotlin:
my string.xml
<string name="price" formatted="false">Price:U$ %.2f%n</string>
my class.kt
var formatPrice: CharSequence? = null
var unitPrice = 9990
formatPrice = String.format(context.getString(R.string.price), unitPrice/100.0)
Log.d("Double_CharSequence", "$formatPrice")
D/Double_CharSequence: Price :U$ 99,90
For an even better result, we can do so
<string name="price_to_string">Price:U$ %1$s</string>
var formatPrice: CharSequence? = null
var unitPrice = 199990
val numberFormat = (unitPrice/100.0).toString()
formatPrice = String.format(context.getString(R.string.price_to_string), formatValue(numberFormat))
fun formatValue(value: String) :String{
val mDecimalFormat = DecimalFormat("###,###,##0.00")
val s1 = value.toDouble()
return mDecimalFormat.format(s1)
}
Log.d("Double_CharSequence", "$formatPrice")
D/Double_CharSequence: Price :U$ 1.999,90
I don't understand this anymore.
I try to write a TextView
android:text="#string/dbVer"
define in strings.xml
<string name="dbVer">db %1$s</string>
and in Activity
int dbTag = Integer.parseInt(yearDay.format(new Date(new File(databasePath + "/ean_database.db").lastModified())));
String dbVer = String.format(getString(R.string.dbVer), dbTag );
The TextView is still showing: db %1$s
The nearest answer I found: Are parameters in strings.xml possible? is similar but in fact something is wrong for me.
It looks like you are getting the result "db %1$s" because you are creating a string and assigning that as its value in the strings.xml file between these ><. What are you trying to have it show instead?
android:text="#string/dbVer"
This refers to your format string and displays the raw format string you're seeing.
int dbTag = Integer.parseInt(yearDay.format(new Date(new File(databasePath + "/ean_database.db").lastModified())));
String dbVer = String.format(getString(R.string.dbVer), dbTag );
This creates a new string dbVer using the format string from resources.
What is missing is that you need to set this new string as your TextView's text:
TextView tv = (TextView)findViewById(R.id.your_textview_id); // assuming an activity
tv.setText(dbVer);
I have strings defined in the usual strings.xml Resource file like this:
<string name="hello_world"> HELLO</string>
Is it possible to define format strings such as the one below
result_str = String.format("Amount: %.2f for %d days ", var1, var2);
in the strings.xml resource file?
I tried escaping the special characters but its not working.
You do not need to use formatted="false" in your XML. You just need to use fully qualified string format markers - %[POSITION]$[TYPE] (where [POSITION] is the attribute position and [TYPE] is the variable type), rather than the short versions, for example %s or %d.
Quote from Android Docs: String Formatting and Styling:
<string name="welcome_messages">Hello, %1$s! You have %2$d new messages.</string>
In this example, the format string has two arguments: %1$s is a
string and %2$d is a decimal integer. You can format the string with
arguments from your application like this:
Resources res = getResources();
String text = res.getString(R.string.welcome_messages, username, mailCount);
You should add formatted="false" to your string resource
Here is an example
In your strings.xml :
<string name="all" formatted="false">Amount: %.2f%n for %d days</string>
In your code:
yourTextView.setText(String.format(getString(R.string.all), 3.12, 2));
Inside file strings.xml define a String resource like this:
<string name="string_to_format">Amount: %1$f for %2$d days%3$s</string>
Inside your code (assume it inherits from Context) simply do the following:
String formattedString = getString(R.string.string_to_format, floatVar, decimalVar, stringVar);
(In comparison to the answer from LocalPCGuy or Giovanny Farto M. the String.format method is not needed.)
Quote from Android Docs:
If you need to format your strings using String.format(String,
Object...), then you can do so by putting your format arguments in the
string resource. For example, with the following resource:
<string name="welcome_messages">Hello, %1$s! You have %2$d new messages.</string>
In this example, the format string has two arguments: %1$s is a string
and %2$d is a decimal number. You can format the string with arguments
from your application like this:
Resources res = getResources();
String text = String.format(res.getString(R.string.welcome_messages), username, mailCount);
For me it worked like that in Kotlin:
my string.xml
<string name="price" formatted="false">Price:U$ %.2f%n</string>
my class.kt
var formatPrice: CharSequence? = null
var unitPrice = 9990
formatPrice = String.format(context.getString(R.string.price), unitPrice/100.0)
Log.d("Double_CharSequence", "$formatPrice")
D/Double_CharSequence: Price :U$ 99,90
For an even better result, we can do so
<string name="price_to_string">Price:U$ %1$s</string>
var formatPrice: CharSequence? = null
var unitPrice = 199990
val numberFormat = (unitPrice/100.0).toString()
formatPrice = String.format(context.getString(R.string.price_to_string), formatValue(numberFormat))
fun formatValue(value: String) :String{
val mDecimalFormat = DecimalFormat("###,###,##0.00")
val s1 = value.toDouble()
return mDecimalFormat.format(s1)
}
Log.d("Double_CharSequence", "$formatPrice")
D/Double_CharSequence: Price :U$ 1.999,90
i have a multilingual android app, where i have put the different translations in the strings.xml in the respective directory.
now i also have a custom xml file, where i would like to reference texts like this:
<?xml version="1.0" encoding="UTF-8"?>
<rooms>
<room title="#+string/localizedtext" />
</rooms>
now when i read the title attribute in my code, i obviously get the unresolved string "#+string/localizedtext" like it is.
is it possible to somehow resolve this link to the localized text automatically?
thanks!
Almost a year later:
public static String getStringResource(Context context, String thingie) {
try {
String[] split = thingie.split("/");
String pack = split[0].replace("#", "");
String name = split[1];
int id = context.getResources().getIdentifier(name, pack, context.getPackageName());
return context.getResources().getString(id);
} catch (Exception e) {
return thingie;
}
}
That'll do it.
This might seem like a broad answer but I believe it'll clarify a lot of things for people who spent hours looking for it (I'm one of them).
The short answer is yes, you can use references in custom XML, not just for strings, but that's the example I use, for ease of understanding.
Considering the context:
res/values/strings.xml
(Default strings, usually en-US for convenience but that's up to the developer)
<resources>
<string name="sample_string">This is a sample string.</string>
</resources>
res/values-fr/strings.xml
(Localized french strings)
<resources>
<string name="sample_string">Ceci est un exemple de chaîne</string>
</resources>
res/xml/test.xml
(Custom XML file)
<!-- #string/sample_string identifies both
the default and french localized strings,
the system settings determine which is used at runtime.
-->
<test>
<sample name="sampleName" text="#string/sample_string"/>
</test>
src/com/example/app/TestXmlParser.java
//Omitted imports for clarity.
public class testXmlParser {
public static final String ns = null;
public int parse(XmlResourceParser parser) throws XmlPullParserException,
IOException{
while(parser.next() != XmlPullParser.END_DOCUMENT){
if(parser.getEventType() == XmlPullParser.START_TAG){
if(parser.getName().equalsIgnoreCase("sample")){
// This is what matters, we're getting a
// resource identifier and returning it.
return parser.getAttributeResourceValue(ns, "text", -1);
}
}
}
return -1;
}
Use String getText(int id) to obtain the string corresponding to id (localized, if available).
Using the example above it would amount to replace :
//Return the resource id
return parser.getAttributeResourceValue(ns, "text", -1);
with :
//Return the localized string corresponding to the id.
int id = parser.getAttributeResourceValue(ns, "text", -1);
return getString(id);
The way you tried is not possible.
You might get similar functionality with <string-array> resource:
<resources>
<string-array name="room">
<item>#string/localizedText</item>
<item>#string/otherLocalizedText</item>
</string-array>
</resources>
then you would use it like this :
String[] room = getResources().getStringArray(R.array.room);
String localizedText = room[0];
String otherLocalizedText = room[1];
Localization in Android is done with resource identifiers. Check out this Android tutorial.
http://developer.android.com/resources/tutorials/localization/index.html
See discussion below.
Great answer kyis, shame I still don't have enough brownie points to rate it. To answer Nick's question, just change the last bit of code to:
int id = parser.getAttributeResourceValue(ns, "text", 0);
return (id != 0) ? getString(id) : parser.getAttributeValue(ns, "text");
Note that I used 0 for the default value of the resource as this is guaranteed never to be a real resource value. -1 would have done also.