skip to Main Content

My App changes the Locale from a press of a button, which works great with an Intent refresh. & once the button is pressed the Locale gets in to the Shared Preferences as well.

I have checked that the Locale is properly saved & retrieved at the start of the app with the correct values.

However, once the app is closed & started again the Locale I believe is changed & Fragment Titles are also changd but the Side Nav Menu titles stay in the default Locale which is English for me.
Inside the Fragments however the Locale is properly changed.

This is the code which I’ve tried on onCreate(), onStart() & also have included in onResume() in the MainActivity extending AppCompatActivity.

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

    hideSystemUI();

    sharedPref = getPreferences(Context.MODE_PRIVATE);
    selectedLanguage = sharedPref.getString("Test.SL.LanguageName", language);
    selectedTheme = sharedPref.getString("Test.SL.ThemeName", "Light");

    if (selectedTheme.equals("Light")){
        AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
    } else if (selectedTheme.equals("Dark")) {
        AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
    }

    language = selectedLanguage;

    Log.i("selectedlang", selectedLanguage);

    if (language.equals("සිංහල")) {
        setAppLocale(this, "si");
    } else if (language.equals("English")){
        setAppLocale(this, "en");
    }

    binding = ActivityMainBinding.inflate(getLayoutInflater());
    setContentView(binding.getRoot());

    setSupportActionBar(binding.appBarMain.toolbar);
    
    drawerLayout = binding.drawerLayout;
    NavigationView navigationView = binding.navView;
    mAppBarConfiguration = new AppBarConfiguration.Builder(
            R.id.nav_a, R.id.nav_d, R.id.nav_a, R.id.nav_settings,
            R.id.nav_about, R.id.nav_disclaimer)
            .setOpenableLayout(drawerLayout)
            .build();
    NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main);
    NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
    NavigationUI.setupWithNavController(navigationView, navController);

}

@Override
public boolean onSupportNavigateUp() {
    NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main);

    return NavigationUI.navigateUp(navController, mAppBarConfiguration)
            || super.onSupportNavigateUp();
}

public void setAppLocale(Context context, String language) {
    Locale locale = new Locale(language);
    Locale.setDefault(locale);
    Configuration config = context.getResources().getConfiguration();
    config.setLocale(locale);
    context.createConfigurationContext(config);
    context.getResources().updateConfiguration(config, context.getResources().getDisplayMetrics());
}

@Override
public void onWindowFocusChanged(boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);
    if (hasFocus) {
        hideSystemUI();
    }
}

private void hideSystemUI() {
SYSTEM_UI_FLAG_IMMERSIVE_STICKY
        View decorView = getWindow().getDecorView();
        decorView.setSystemUiVisibility(
                View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
                        | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                        | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                        | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                        | View.SYSTEM_UI_FLAG_FULLSCREEN
                        | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
    }

private void showSystemUI() {
    View decorView = getWindow().getDecorView();
    decorView.setSystemUiVisibility(
            View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}

Please let me know how I can correct whatever I’m doing wrong. Thank you very much!

Launcher Activity as Simple UX Apps mentioned but it does not seem to work still, unless again I’m doing something wrong in this particular code.

public class Launcher extends AppCompatActivity {

String language = "English";


private SharedPreferences sharedPref;
private String selectedLanguage;
private String selectedTheme;

@Override
protected void onStart() {
    super.onStart();

    sharedPref = getPreferences(Context.MODE_PRIVATE);
    selectedLanguage = sharedPref.getString("Test.SL.LanguageName", language);
    selectedTheme = sharedPref.getString("Test.SL.ThemeName", "Light");

    if (selectedTheme.equals("Light")){
        AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
    } else if (selectedTheme.equals("Dark")) {
        AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
    }

    MainActivity.language = selectedLanguage;
    language = selectedLanguage;

    Log.i("selectedlang", selectedLanguage);

    if (language.equals("සිංහල")) {
        setAppLocale(this, "si");
    } else if (language.equals("English")){
        setAppLocale(this, "en");
    }
}

public void setAppLocale(Context context, String language) {
    Locale locale = new Locale(language);
    Locale.setDefault(locale);
    Configuration config = context.getResources().getConfiguration();
    config.setLocale(locale);
    context.createConfigurationContext(config);
    context.getResources().updateConfiguration(config, context.getResources().getDisplayMetrics());
    Intent refresh = new Intent(getApplicationContext(), MainActivity.class);
    startActivity(refresh);
    finish();
}
}

2

Answers


  1. Chosen as BEST ANSWER

    After messing with it a quite bit I couldn't figure out why only the Drawer Layout is not pulling the resources from the correct locale string file.

    So since everything works as it should with the selected locale the logical thing to do was to change the Drawer Layout item titles at onCreate in the MainActivity.

    I used a method from this post to retrieve the locale specific strings for the titles

    The code before the & after the below snippet are as is on my original question.

        drawerLayout = binding.drawerLayout;
        NavigationView navigationView = binding.navView;
    
        navigationView.getMenu().findItem(R.id.nav_a)
                .setTitle(getLocaleString(R.string.menu_a, selectedLocale));
        navigationView.getMenu().findItem(R.id.nav_d)
                .setTitle(getLocaleString(R.string.menu_d, selectedLocale));
        navigationView.getMenu().findItem(R.id.nav_ar)
                .setTitle(getLocaleString(R.string.menu_ar, selectedLocale));
        navigationView.getMenu().findItem(R.id.nav_tools)
                .setTitle(getLocaleString(R.string.menu_tools, selectedLocale));
        navigationView.getMenu().findItem(R.id.nav_settings)
                .setTitle(getLocaleString(R.string.menu_settings, selectedLocale));
        navigationView.getMenu().findItem(R.id.nav_about)
                .setTitle(getLocaleString(R.string.menu_about, selectedLocale));
        navigationView.getMenu().findItem(R.id.nav_disclaimer)
                .setTitle(getLocaleString(R.string.menu_disclaimer, selectedLocale));
    
        mAppBarConfiguration = new AppBarConfiguration.Builder(
                R.id.nav_a, R.id.nav_d, R.id.nav_ar, R.id.nav_settings,
                R.id.nav_about, R.id.nav_disclaimer)
                .setOpenableLayout(drawerLayout)
                .build();
    

    & to retrieve the strings

    public String getLocaleString(int id, String lang){
        Resources res = getResources();
        Configuration conf = res.getConfiguration();
        conf.locale = new Locale(lang);
        DisplayMetrics metrics = new DisplayMetrics();
        Resources resources = new Resources(getAssets(), metrics, conf);
        String string = resources.getString(id);
        return string;
    }
    

    If there is a better solution please do let me know!


  2. Create another activity as the launcher activity.

    Then declare the new launcher activity in your manifest like this:

    <activity android:name="com.sux.alarmclocknew.LauncherActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
    
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    

    Put the code where you set the locale in your new LauncherActivity.
    After you set the locale, launch MainAcitivty from LauncherActivity.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search