Android change language in app only: Some strings not translated properly
Asked Answered
B

4

6

(I've added an update on the bottom of the post)

I am currently working on a project that will support multiple language. I have written all strings for all languages.

I use BaseActivity, Application class, and LocaleHelper to manage the localization on my app. And then I found this behavior on my app. After I setLocale to another language, Strings in some activities are changed and correct, but NOT in MainActivity even though they have some same strings. I tried to restart app and it's still not working.

I also have another activity which some of the words in activity got translated but all words inside a fragment and a recyclerview didn't get translated at all.

I still couldn't find why it's not translated properly. Can someone help me??

Here's some snippet:

Application class

@Override
public void onCreate() {
    super.onCreate();
    LocaleUtil.setLocale(new Locale(LocaleUtil.with(this).getPreference()));
    LocaleUtil.updateConfig(this,getBaseContext().getResources().getConfiguration());
}

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    LocaleUtil.setLocale(new Locale(LocaleUtil.with(this).getPreference()));
    LocaleUtil.updateConfig(this, newConfig);
}

BaseActivity

public BaseActivity() {
    LocaleUtil.updateConfig(this);
}

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    initLocale();
    super.onCreate(savedInstanceState);
}

public void initLocale(){
    localeUtil = new LocaleUtil(this);
    localeUtil.setListener(this);
    localeUtil.setLanguageByCode(localeUtil.getPreference());
}

Please help me! THanks!!

(UPDATE)

I found out that I have to setLocale again whenever I want to access Strings.xml for any views in a recyclerview and a fragment. This is totally inconvenient and I'm worried about the performance. I would love to hear a better advice to change language.

Benisch answered 3/11, 2017 at 3:10 Comment(3)
You really aren't meant to directly change the locale like that. It mostly works, but the way the system is meant to work is for you to follow the system locale and never change it yourself. If you want to change it yourself you're almost better off writing your own system of strings.Enslave
Hello there! Sorry maybe I write wrong title. what I mean is that I have this "change language" setting on my app, I need to change language only on app. Can you explain more or give reference about how to write our "own system of strings"? Thanks!Benisch
did you find any solution? I am having the same issue.Emphatic
R
2

Check this out. Maybe some string is not include. From documentation.

https://developer.android.com/guide/topics/resources/localization.html#using-framework

Suppose that your application's default language is English. Suppose also that you want to localize all the text in your application to French, and most of the text in your application (everything except the application's title) to Japanese. In this case, you could create three alternative strings.xml files, each stored in a locale-specific resource directory:

res/values/strings.xml Contains English text for all the strings that the application uses, including text for a string named title. res/values-fr/strings.xml Contain French text for all the strings, including title. res/values-ja/strings.xml Contain Japanese text for all the strings except title. If your Java code refers to R.string.title, here is what will happen at runtime:

If the device is set to any language other than French, Android will load title from the res/values/strings.xml file. If the device is set to French, Android will load title from the res/values-fr/strings.xml file. Notice that if the device is set to Japanese, Android will look for title in the res/values-ja/strings.xml file. But because no such string is included in that file, Android will fall back to the default, and will load title in English from the res/values/strings.xml file.

I hope it will work.

Rearm answered 3/11, 2017 at 3:25 Comment(0)
I
1

I had the same issue as you. The language changes in Activities but doesn't change in Fragments. I tried it on more than one device, all had the same result. Later, I figured out a solution and it does work for me.

Solution: Inside the Android Studio, go to the "Build" tab, select "Clean Project". Wait until it finished. (A loading bar is placed at the bottom right corner indicating the progress rate) Next, go to the "Build" tab again, select "Rebuild Project". When it finished rebuilding, the problem should be solved.

Hope this help.

Indo answered 22/7, 2018 at 10:55 Comment(0)
W
1

This happened to me as well, what I did is I set text from Java/Kotlin instead of XML. I did this for headings as well though in my case headings are not changing.

Wyatt answered 8/12, 2021 at 16:19 Comment(1)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Astrict
C
0

In my case I had to attachBaseContext in MainActivity

class MainActivity : AppCompatActivity() {

override fun attachBaseContext(newBase: Context) {
    val languageCode = (newBase.applicationContext as? MyApp)?.getSavedLanguage(newBase) ?: "en"
    val contextWithLanguage = (newBase.applicationContext as? MyApp)?.applyLanguage(newBase, languageCode) ?: newBase
    super.attachBaseContext(contextWithLanguage)
}

and In MyApp:

fun getSavedLanguage(context: Context): String? {
    val sharedPreferences = context.getSharedPreferences("settings", Context.MODE_PRIVATE)
    return sharedPreferences.getString("app_language", null)
}

EDIT: added BaseActivity to make it work for all other activities:

open class BaseActivity : AppCompatActivity() {

// need this workaround to have initial language in all inherited fragments
override fun attachBaseContext(newBase: Context) {
    val languageCode = (newBase.applicationContext as? MyApp)?.getSavedLanguage(newBase) ?: "en"
    val contextWithLanguage = (newBase.applicationContext as? MyApp)?.applyLanguage(newBase, languageCode) ?: newBase
    super.attachBaseContext(contextWithLanguage)
}

} eg:

class AddServiceEntryActivity : BaseActivity() {
Couch answered 29/10 at 13:7 Comment(1)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Astrict

© 2022 - 2024 — McMap. All rights reserved.