Labels loose value change of orientation with internationalization android - android

I'm developing an Android app that uses Internationalization.
So i have the folders values-language (e.g. values-en, values-br) in my solution. The internationalization is working well.
The problem is when i combine it with orientation elements.
I have also one xml file for landscape and other for portrait. I have the folders layout-orientation (e.g layout-port). The orientation is working well too. I accomplish this by overhiding the following method:
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
setContentView(R.layout.main);
}
But i'm having problems with the string values (labels). When i change the orientation, all the string values loose data and appers as ids. For example, I have a button that has a label "SAVE". When i rotate my phone, the label of the button changes to "#23232324" which is the number of the resource.
What can I do? I've tried to create portrait and landscape folders for each language that I have but didn't work (e.g values-br-port, values-br-land).
I need to keep both working, orientation and internationalization. I need to have two different layouts based on the orientation and also different languages.

BTW, I got it solved!!
The problem was that i was not calling the method setLocale before reloading the view.
So i had to do,
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
setLocale();
setContentView(R.layout.main);
}
And the method setLocale:
public void setLocale(){
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config,
getBaseContext().getResources().getDisplayMetrics());
}

Related

make multi language android application

I created multi language (English, Russian, Uzbek) app. I put 4 string resoureses in 4 folders (values, values-en, values-ru, values-uz) as docs. When I change app language updates resourses configuration in App Controller like below:
Settings.LANGUAGE = prefs.getString(User.LANG, Settings.RUSSIAN);
Locale locale = new Locale(Settings.LANGUAGE);
Locale.setDefault(locale);
Configuration configuration = new Configuration();
configuration.locale = locale;
getBaseContext().getResources().updateConfiguration(configuration,
getBaseContext().getResources().getDisplayMetrics());
After that App restarts by calling App controller's method like below:
public void reStart() {
Intent i = getBaseContext().getPackageManager()
.getLaunchIntentForPackage(getBaseContext().getPackageName());
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
}
After them It works well almost all devises. But on Samsung Galaxy S6 (SM-G920F), it works as crazy. Some words are in english and others are in Uzbek and ets.
So, How to fix this error? isn't the concepts of "Supporting Different Languages" supported by (applicable to) all devices?
By the way, I have checked that all resources are given in corresponding languages (as shown in attached image):
From my observations, weird behaviour was affecting only Activity titles, and I found that I was setting translations of activity titles in Manifest file. Only these translations were misbehaving. All other dynamically set translations were working fine.
So, to fix the problem, I removed all activity labels from Manifest file, then set activity titles in onCreate method as below:
getSupportActionBar().setTitle(R.string.title_activity_followers);
Problem solved.

Locale: onConfigurationChanged not called

I want my language to change dynamically and I am trying to use onConfigurationChanged but it is not being called. I have a MainActivity that creates my action bar and viewpager. The rest of my pages are Fragments. In my SettingsFragment I have a button to switch the language to French.
langChange.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View vi) {
MainActivity main = (MainActivity)getActivity();
main.langChange();
}
});
Then in my MainActivity I have
#Override
public void onConfigurationChanged(Configuration newConfig){
super.onConfigurationChanged(newConfig);
if (locale != null){
newConfig.locale = locale;
Locale.setDefault(locale);
getBaseContext().getResources().updateConfiguration(newConfig, getBaseContext().getResources().getDisplayMetrics());
}
}
public void langChange(){
if(currentLanguage == FRENCH_LANGUAGE){
locale = new Locale("en");
Locale.setDefault(locale);
Configuration c = getBaseContext().getResources().getConfiguration();
c.locale = locale;
getBaseContext().getResources().updateConfiguration(c,getBaseContext().getResources().getDisplayMetrics());
currentLanguage = "English";
}
else if(currentLanguage == ENGLISH_LANGUAGE){
locale = new Locale("fr");
Locale.setDefault(locale);
Configuration c = getBaseContext().getResources().getConfiguration();
c.locale = locale;
getBaseContext().getResources().updateConfiguration(c,getBaseContext().getResources().getDisplayMetrics());
currentLanguage = "French";
}
actionBar.setSelectedNavigationItem(actionBar.getTabCount() - 1); //This just puts it back to the settings tab
}
The onConfigurationChanged is not being called. In my manifest I have:
<activity android:name="MainActivity" android:screenOrientation="portrait" android:configChanges="locale"></activity>
I have tried adding one or all of these options orientation|keyboardHidden|screenSize with no success.
The reason for all of this is because I want to change the actionBar text and all the other text once I click the button. I have a separate strings file for French.
Any help would be great.
You have to define android:configChanges="layoutDirection|locale" in order for onConfigurationChanged() to be called.
Ok, I've looked into this a bit.
I'm not sure, why the onConfigurationChanged method isn't called, so I'm hoping someone can enlighten us on this part.
In my search I stumbled upon this tutorial , which actually change the Locale, by changing the configuration.
Your code looks a lot like this tutorial actually ;-)
Anyways, the important thing about the tutorial and the code is this method:
private void updateTexts() {
txt_hello.setText(R.string.hello_world);
btn_en.setText(R.string.btn_en);
btn_ru.setText(R.string.btn_ru);
btn_fr.setText(R.string.btn_fr);
btn_de.setText(R.string.btn_de);
}
This is where the "magic" happens; after you've changed your locale you will need to reload your resources and since you told Android you want to handle some configurations on your own you need to specifically reload all your text, by setting your UI items texts again.
When this is done, the app will load the strings from the specific locales folder.
The answer to why Android behaves this way, can be found in the official documentation for the Activity saying:
[...]
This is done because any application resource, including layout files, can change based on any configuration value. Thus the only safe way to handle a configuration change is to re-retrieve all resources, including layouts, drawables, and strings. Because activities must already know how to save their state and re-create themselves from that state, this is a convenient way to have an activity restart itself with a new configuration.
The guy writing the tutorial was kind enough to add the whole tutorial project as a download, so I recommend you go check it out to see how it's working, because it is working ;-) You can outcomment the onConfigurationChanged method, as it doesn't seem to be doing anything.
Hope this helps.

Change Text on Landscape mode with Java Code and not XML (Android)

I wrote my layout entirely in java code because it was just more convenient. (I had a lot of textViews and using for statements were more convenient).
However, my TextViews require the day of the week and in portrait mode, I would like to cut the day of the week to a short form. For example, I want "Sunday" to show "Sun" for portrait mode, but "Sunday" for landscape mode.
I understand how to do this in XML files, but how do I do it in code?
I.e. sample code:
LinearLayout parent = new LinearLayout(getApplicationContext());
parent.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT));
TextView example = new TextView;
example.setLayoutParams(mparams);
example.setText("Sunday"); //<--make this "Sun" when in portrait but "Sunday" in landscape
parent.addView(example);
If your application is getting restarted when it moves to landscape then you can define the strings that need to be expanded in Landscape mode in values-land
And it is never a good idea to use hard coded strings. Even if you are creating layouts programmatically use strings.xml to store strings
You can override the onConfigurationChanged() method in your Activity class, and you can set your text, when orientation will change this method will call... Hope it will helpful to you..:)
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
// Here you can set text **Sun**
} else if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
//Here you can set text **Sunday**
}
}

changing locale in app on Android 2.2 platform (on Android 4.0 is ok) in my case

I would like to change my app locale programmatically. I use the following code to do the task which is in onCreate() method of Activity:
#Override
protected void onCreate(Bundle arg0) {
super.onCreate(arg0);
Resources res = context.getResources();
DisplayMetrics dm = res.getDisplayMetrics();
Configuration config= new Configuration();
config.locale = new Locale("fr"); //use French locale
res.updateConfiguration(config, dm);
//following code will navigate among fragments
...
}
My app only has one Activity which hosts several fragments.
If I run my app on Android 4.0 platform, it is working nicely, every fragment display with "French" language.
But if I run on Android 2.2 platform, only the first fragment display in French language, the next replaced fragment still show English (my phone setting use English locale).
Why it works only on Android 4.0 platform ??
It looks like some bug in Android 2.x
Because if you change locale not in onCreate() but in createMenu() or inside some spinner.setOnItemSelectedListener() it will work.
It is workaround but try to call some event after start your app and change locale in it.

Localize Android application so I can switch locale inside app

How do I localize application so it uses specific locale regardless of what locale set on device? I want make it possible for users to set language of their choice.
So far I have code like this in my Application class:
#Override
public void onCreate()
{
//Set locale
String l = Preferences.getLocale(getApplicationContext());
if (!l.equals(""))
{
Locale locale = new Locale(l);
Locale.setDefault(locale);
Configuration config = getBaseContext().getResources().getConfiguration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(
config, getBaseContext().getResources().getDisplayMetrics());
}
LogData.InsertMessage(getApplicationContext(), "Application started");
}
Problem that I have is that it seems like I display in set locale just fine (TextViews)
But Menu captions and toasts will fall to default locale.
Is there any 1-2-3 on how to get it working properly? I uses 2.2 version
This post explains how to force localization in your app.
Ok, I figured why I had this problem.. I needed to override onConfigurationChanged in my application class. That is much more elegant solution than to specify locale on each Activity.

Categories

Resources