Compare strings independently of current language - android

i'm having a hard time trying to understand how to deal with language - and trying to explain myself in english.
For example, take a look at this
<resources>
<string name="temperature_celsius">Celsius</string>
<string name="temperature_fahrenheit">Fahrenheit</string>
<string name="temperature_kelvin">Kelvin</string>
<string-array name="temperature">
<item>#string/temperature_celsius</item>
<item>#string/temperature_fahrenheit</item>
<item>#string/temperature_kelvin</item>
</string-array>
</resources>
Now, imagine that i have another xml file where Celsius, Fahrenheit and Kelvin are written differently in another language.
//name of temperature units in another galaxy
<resources>
<string name="temperature_celsius">Celsioso</string>
<string name="temperature_fahrenheit">Fahrenheitzkeum</string>
<string name="temperature_kelvin">Kalvon</string>
<string-array name="temperature">
<item>#string/temperature_celsius</item>
<item>#string/temperature_fahrenheit</item>
<item>#string/temperature_kelvin</item>
</string-array>
Now, i want my alien user to see the units in its own language, so i need to compare them taken that into account. Is there an efficient way in which i could do this instead of hardcoding the value of each string item? I tried using a switch but it says constant expression required, i think it works if i use if-else, but it looks ugly:
//convert from celsius(baseUnit) to something else(endUnit)
//baseUnit and endUnit are strings taken from two autocompletetextviews
if(baseUnit.equals(mContext.getResources().getString(R.string.temperature_celsius))) {
convertFromCelsius(endUnit, inputValue, mContext);
I'm handling the UI in my main activity, the job of converting each unit is done in other java classes (that's why i'm using a mContext).
Thanks, and sorry for my bad english.

Related

How can i create nested array in android studio Strings.xml

<resources>
<string name="app_name">UnConv</string>
<string-array name="mainunit">
<item>Area</item>
<item>Pressure</item>
<item>Speed</item>
<item>Volume</item>
</string-array>
</resources>
i want to add some other values to the above items like a subgroup. Example for area i want yard, acre etc how can i achieve that?
Unfortunately, There is no direct way to save two dimensional string-array in Android resource file. I provide 2 methods for replacement.
1. Save the data as Json string showing in the following code:
<string name="mainunit">{"Area":["yard","acre"],"Pressure":[],"Speed":[],"Volume":[]}</string>
Then parse Json String to Java/Kotlin Object.
2. Save subgroup value splitting with ",", and get value by position, but it has drawback because it ignored the key name.
<string-array name="mainunit">
<item>yard,acre</item>
<item>Pressure</item>
<item>Speed</item>
<item>Volume</item>
</string-array>

Efficient Android resource override for regional users

I have an app originally written in UK English, hence all of the strings in res/values/strings.xml are in UK English.
I would like to provide a "translation" to US English. For the most part US and UK English are exactly the same, so in the US translation file I only want to specify those few string changes which are affected (about 10 of 120).
I have tried creating a res/values-en-rUS/strings.xml file (this name given by Android Studio) in which I've added only those 10 strings which differ. But Android Studio gives me errors in my main strings.xml for all the remaining strings: "XXX" is not translated in "en" (English).
So, how can I efficiently provide translations to US English - ie specify only the 10 lines, without having to duplicate all the others? Duplication is always bad for code maintenance!
You can use translatable="false" settings to flag string resources that should not be translated. Something like:
<resources>
<string name="app_name" translatable="false">EasyApp</string>
<string name="action_settings">Settings</string>
<string name="easy_app">I am a Simple App!</string>
<string name="next_page">Next Page</string>
<string name="second_page_message">I am the Second Page!</string>
<string name="title_activity_second">SecondActivity</string>
</resources>
In the above sample, the app_name will not have to be translated in other locales. This way in the default strings.xml you can provide the UK version and mark with translatable="false" all the resources that you would like to maintain in US version to be the same. In res/values-en-rUS/strings.xml you will have to add only the messages that you need to maintain in US English.
Please note that if you are planning to use other locales/languages this method may not be the appropriate one, since this way you specify that the translatable="false" resources are the same for all locales.
You can check the Configure untranslatable section rows if you need more details.

Android strings xml similar texts

In my Android app I'm using strings.xml for all texts. I have many situations where I use almost the same string,
e.g. "Name" and "Name:" - translation is the same only additional colon is difference.
Is there any other way to have these two string except creating two string items like this:
<string name="name">Name</string>
<string name="name2">Name:</string>
There is no way you can concatenate strings in the strings.xml file.
All you can do is specify the format,
<string name="name">Name</string>
<string name="string_with_colon">%s:</string>
Then pass the name programatically,
String.format(getString(R.string.string_with_colon), getString(R.string.name));
Yes, you can do so without writing any Java/Kotlin code, only XML by using this small library I created which does so at buildtime: https://github.com/LikeTheSalad/android-stem
Usage
Based on your example, you'd have to set your strings like this:
<string name="name">Name</string>
<string name="name2">${name}:</string>
And then after building your project, you'll get:
<!-- Auto generated during compilation -->
<string name="name2">Name:</string>

Is concatenation of resource strings/string concatenation, possible in layout file?

I have resource strings :
<string name="address">Address</string>
<string name="city">City</string>
<string name="country">Country</string>
<string name="pincode">Pincode</string>
In my application, at few places I am using these strings alone and at few places I am succeeding them by a colon.
I don't what to create another four resource strings :
<string name="address_with_colon">Address: </string>
<string name="city_with_colon">City: </string>
<string name="country_with_colon">Country: </string>
<string name="pincode_with_colon">Pincode: </string>
Now to achieve this, I have to concatenate my resource strings with colon. I know this is very easy though java code which I can write in my activity class. But what I want is to do the concatenation in my layout file.
Question : Is string concatenation possible in layout file?
This is where I have to perform the concatenation:
android:text="concatenation_if_possible"
Using XML entities it's possible to use the same string multiple places within an XML file:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE resources [
<!ENTITY appname "MrQuery">
<!ENTITY author "Oded">
]>
<resources>
<string name="app_name">&appname;</string>
<string name="description">The &appname; app was created by &author;</string>
</resources>
I used this answer: dynamic String using String.xml?
Question : Is string concatenation possible in layout file?
Nope as far as I know.
One solution is to use what #DIVA has answered before.
Another possible solution is to create a custom view that extends TextView (or the view you want to achieve this) and create a custom attribute custom:concatenate which receives a string reference and perform the concatenation automatically. IMHO I think this is the most clean approach.
In code will look as this:
<com.whatever.ConcatenateTextView
android:text="#string/whatever"
custom:concatenate="#string/second_string"/>
Or… you can use the power of Drawables creating a custom TextDrawable (which is explained very well by #Devunwired in this post and the concrete implementation of it in Github).
Copying what #Devunwired has said in his post about it:
With this class, text can now be part of the Drawable world, meaning it can not only be set alone in places where you would normally put an image, it can also be placed together with other Drawables in containers like StateListDrawable or animated with the likes of TransitionDrawable and ClipDrawable. In many cases, we can use this to do a job that would otherwise require multiple views or compound controls just to achieve a given visual effect; thus it can reduce overhead in your view hierarchy.
This combined with your custom TextView as I explained before (or whatever view you want to use) gives you a very powerful option. Again copying the example that #Devunwired wrote in his post:
ImageView mImageOne;
TextDrawable d = new TextDrawable(this);
d.setText("SAMPLE TEXT\nLINE TWO");
d.setTextAlign(Layout.Alignment.ALIGN_CENTER);
mImageOne.setImageDrawable(d);
If you need more help please let me know in the comments and I'll gladly update the answer!
You can so something like this :
<string name="meatShootingMessage">You shot %1$d pounds of meat!</string>
String strMeatMsg = String.format(strMeatFormat, ":");
textview.setText(strMeatMsg);
No, you cannot concatenate several string resources into a single string when directly referencing those strings from a layout file.
XML layout files are simply a template of instructions for Android to build a user interface, and you should consider them as a cleaner and more organized way to generate your UI than using a Java class that manually creates and positions views in a layout. That being said, there are limitations to what you can do with a layout file, and one of them is being able to reference a single string resource from every view, meaning that you can't do anything more complex than that, including concatenating several strings into one.
You can do so using this plugin I've created: https://github.com/LikeTheSalad/android-stem It will concat all of the strings you'd like to and will generate at build time a final XML string that you can reference anywhere as with any other manually string you've added.
For your case, you can do the following:
<string name="address">Address</string>
<string name="city">City</string>
<string name="country">Country</string>
<string name="pincode">Pincode</string>
<string name="address_with_colon">${address}: </string>
<string name="city_with_colon">${city}: </string>
<string name="country_with_colon">${country}: </string>
<string name="pincode_with_colon">${pincode}: </string>
And then the tool will generate:
<!-- Auto generated during compilation -->
<string name="address_with_colon">Address: </string>
<string name="city_with_colon">City: </string>
<string name="country_with_colon">Country: </string>
<string name="pincode_with_colon">Pincode: </string>
And anytime you decide to change either your template or values strings, the plugin will keep the generated strings updated. More info on the repo's page.

Are "strings.xml" string arrays always parsed/deserialized in the same order?

Can I count on string arrays within the "strings.xml" resource file to be parsed/deserialized in the same order every time?
If anyone can cite any documentation that clearly spells out this guarantee, I'd appreciate it. Or, at the very least, offer a significant amount of experience with this topic.
Also, is this a best practice or am I missing a simpler solution?
Note: This will be a small list, so I'm not looking to implement a more complicated database or custom XML solution unless I absolutely have to.
<!--KEYS (ALWAYS CORRESPONDS TO LIST BELOW ??)-->
<string-array name="keys">
<item>1</item>
<item>2</item>
<item>3</item>
</string-array>
<!--VALUES (ALWAYS CORRESPONDS TO LIST ABOVE ??)-->
<string-array name="values">
<item>one</item>
<item>two</item>
<item>three</item>
</string-array>
Yes, as far as I'm aware you can assume that the order of items will be the same each time, meaning you can safely define key/value pairs using separately xml-declared arrays. Have a look at the API demos (e.g. the arrays.xml file) and you'll see that Google uses the same methodoly to specify static key/value pairs. More specifically, you'll be able to deduce this from entries_list_preference and entryvalues_list_preference. Actually, if you think about it: it would hardly make sense to offer entries and entryValues attributes for pointing to static resources for e.g. a ListPreference if their order wouldn't be guaranteed.
Addendum: Multi-dimensional arrays in xml are not supported. You can however write your own xml parser to handle those cases, which actually isn't as hard as it may sound. It would probably take you more time though than simply defining two one-dimensional arrays.

Categories

Resources