I'm working an Android app and want to translate it to Persian language.
All String values in the project are saved into an resource XML file.
Some String values are used in layout files and some in classes (R.String). When using Persian text in Android, it has to be reshaped to be displayed correctly.
I want to reshape all resource String values without calling reshape method for every String value.
Can anyone explain me how to do this?
Some idea:
override String class
override getResource class
Android provides already functionality (well documented) to have a multilanguage app. Instead of replacing your text and having severall versions of your app for each language, its better to use the frameworks function. In that case the app chooses a suitable language from the available languages you provided depending on the device locale settings.
So basically you would start by creating the required directory structure (link above):
MyProject/
res/
values/
strings.xml
values-fa/
strings.xml
and then you fill in String values into the files, e.g.:
English (default locale), /values/strings.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="title">My Application</string>
<string name="hello_world">Hello World!</string>
</resources>
Persian, /values-fa/strings.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="title">...</string>
<string name="hello_world">...</string>
</resources>
(quoted and adapted from the link above)
Solution for reshape farsi language
The reshape function has to be used for every Farsi String value, so setting string in the XML layout isn't possible (AFAIK), so the following proposals assume, that all String values are set programatically.
Using a global static wrapper function #1
public static final String getLocalizedString(int resId) {
if(Locale.getDefault().toString().equals("fa_IR")) {
return PersianReshape.reshape(getResources().getString(resId));
}else{
return getResources().getString(resId);
}
You can now use this function to load the String (you have to change each occurence) or you override e.g. the getRessource method. I personally would prefer using a static function instead of overriding because of possible other problems regarding loading resources of other type than String, side effects etc.
Creating a custom class with overriding setText() for each used ui widgets #2
Another possibility is to create custom ui widgets that do a call to PersianReshape.reshape() when display. E.g. for EditText:
class CustomTextField extends EditText {
#Override
public void setText(String text) {
super.setText(PersianReshape.reshape(text));
}
}
[...]
CustomTextField myTextBox = new CustomTextField();
myTextBox.setText("....");
Related
I am working with an Android app, which shows some text in Bengali.
This sentence is in the app resources string file:
<resources>
<string name="sentence">১৯৭৫ সালে বিল গেটস(Bill Gates) এবং পল এলেন(Paul Allen) একসাথে "মাইক্রোসফট"("MicroSoft") নামক কোম্পানি প্রতিষ্ঠা করেন, যেটা পরবর্তীতে পৃথিবীর সবচেয়ে বড় পিসি কোম্পানির মর্যাদা পায়।</string>"
</resources>
I want to show this whole sentence in Bengali, so I set typeface to my textview and I can use different Bengali fonts, but the problem is I need to show names (Bill Gates, Paul Allen and Microsoft) in English instead of Bengali font. How can I do it?
You can use HTML commands in your text view and then apply different typefaces to different parts of this TextView.
You can do this:
textView.setText(Html.fromHtml("<font size=... color=... face=...>" + getString(R.string.sentence) + "</font>"))
This would set the typeface of the whole sentence to the defined one. To do this only on parts, save the String resource to a local variable, and then apply the different Html commands to the desired parts.
Also see here and for the allowed Html tags here
I'm working on a project where I've defined several strings to use on my project.
I want to use a string to be displayed as my subtitle of the page on the toolbar. The reason I'm using strings is because I want my app to be translation supported.
Here is how I use subtitles on the toolbar of my activity:
android.support.v7.app.ActionBar ab = getSupportActionBar();
ab.setTitle("Title");
ab.setSubtitle("Subtitle");
I want to use a string on java (like #string/helloworld in xml) but I don't know how can I do that.
Can anyone help me?
In your "res" directory, there might be "strings.xml" file. (If you didn't remove it). Add string tags like bellow code snippets.
<string name="title">Title Message</string>
<string name="sub_title">Sub Title Message</string>
And in your java file.
String mStringTitle = getString(R.string.title);
String mStringSubTitle = getString(R.string.sub_title);
You can also use these string resources in your layout XML like follows.
<TextView
android:text="#string/title" />
For more information, please refer to the bellow URLs.
What is the string resource in Android? android_string_resources
How to support multiple locales?
support_different_language //
different-locales
In this case, use R.string.helloworld, because these methods require a resource ID.
This is the code -
R.string.message_failure
Implementation of the above code -
snackbar = Snackbar.make(constraintLayout,R.string.message_failure, Snackbar.LENGTH_SHORT)
//String_file.xml code -
<string name="message_failure">Failure</string>
I've read others posts about this link warning but they didn't solve my problem and I still don't get what I've doing wrong.
In default file strings.xml, I have:
<string name="rating_dialog">You\'re about to rate this app with %s stars.</string>
Later, I call it inside an override onClick method:
v.getContext().getString(R.string.rating_dialog, String.valueOf(rating))
It's appearing like:
You're about to rate this app with {String.valueOf(rating)} stars.
Link Warning:
Format string is not a valid format string so it should not be passed to string.format
Note:
v is a View and rating is an int value.
I've checked other strings.xml files for other languages, and all translations seems alright.
Solved: for hindi string.xml, instead of %s, there was only %.
You need to assign a position to each placeholder you define in your XML.
Your string then becomes:
<string name="rating_dialog">You\'re about to rate this app with %1$s stars.</string>
You can do it like below:
In string.xml:
If you want to assign integer value then use "%1$d" and if String then use "%1$s"
1 is use for defining position. If you want to use multiple values then you can use "%1$d","%2$d",....etc
<string name="rating_dialog">You\'re about to rate this app with %1$d stars.</string>
Then in code do it like :
v.getContext().getString(R.string.rating_dialog, rating);
Hope it helps you.
I know how to create a simple Array in xml like this
<resources>
<string-array name="countries_array">
<item>Afghanistan</item>
<item>Albania</item>
<item>Algeria</item>
<item>American Samoa</item>
<item>Andorra</item>
<item>Angola</item>
<item>Anguilla</item>
<item>Antarctica</item>
</string-array>
</resources>
And then I initialize it like this in code
ArrayAdapter<String> adapter =
new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, countries_array);
textView.setAdapter(adapter);
But I want to store more items than just a string, so I need a way to store an arraylist rather than a simple array.
Like below
<resources>
<Share>
<name>Apple</name>
<currentRate>5.69</currentRate>
<changeToday>-0.11</changeToday>
<changeTodayPercent>-0.02</changeTodayPercent>
<timeUpdated>2012,12,06,18,00,00</timeUpdated>
<Share>
<Share>
<name>Microsoft</name>
<currentRate>5.88</currentRate>
<changeToday>0.19</changeToday>
<changeTodayPercent>+0.09</changeTodayPercent>
<timeUpdated>2012,12,06,18,00,00</timeUpdated>
<share>
...
</resources>
I already have a class called Share.java with following variables that need to be set via setMethods
public class ShareHolding {
private String name;
private double currentRate;
private double changeToday;
private double changeTodayPercent;
private GregorianCalendar timeUpdated;
}
and add them to an arraylist
ArrayList<Share> allShares = new ArrayList<Share>();
allShares.getShare(0).setName("I want to access my xml file here and add the first shares name here");
As far as I know, you won't be able to mismatch data types using the resource file. The resource only supports one-way datatypes. e.g Array of string, array of integers, etc.
The best solution that would work is to make the Share xml into it's own file and parse is into your shared object. The android developer has some example of the built in xml parser
Just a quickie,
i have an xml resource in res/values/integers.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<integer-array name="UserBases">
<item>2</item>
<item>8</item>
<item>10</item>
<item>16</item>
</integer-array>
</resources>
and ive tried several things to access it:
int[] bases = R.array.UserBases;
this just returns and int reference to UserBases not the array itself
int[] bases = Resources.getSystem().getIntArray(R.array.UserBases);
and this throws an exception back at me telling me the int reference R.array.UserBases points to nothing
what is the best way to access this array, push it into a nice base-type int[] and then possibly push any modifications back into the xml resource.
I've checked the android documentation but I haven't found anything terribly fruitful.
You need to use Resources to get the int array; however you're using the system resources, which only includes the standard Android resources (e.g., those accessible via android.R.array.*). To get your own resources, you need to access the Resources via one of your Contexts.
For example, all Activities are Contexts, so in an Activity you can do this:
Resources r = getResources();
int[] bases = r.getIntArray(R.array.UserBases);
This is why it's often useful to pass around Context; you'll need it to get a hold of your application's Resources.
get an array from xml resources of android project can be accessed.
from array.xml
<string-array name="weather_values">
<item>sunny</item>
<item>cloudy</item>
<item>rainy</item>
</string-array>
in Activity
String[] stringsArray = getApplicationContext().getResources().getStringArray(R.array.weather_values);
in Fragment
String[] stringsArray = getContext().getResources().getStringArray(R.array.weather_values);
for output in log
System.out.println("Array Values " + Arrays.toString(stringsArray));
output is
I/System.out: Array Values [sunny, cloudy, rainy]