Search code examples
androidandroid-studiolocale

Changing the locale of the Navigation drawer items and fragment Activities


When I change the locale of the app, every TextView changes the language but fragment activities(activities opened from fragment) and navigation drawer items don't change the language. Have a look at this Multiple Language for code reference.

The problem is after locale change, only fragments language is changing. I searched over the internet but found no reasonable answer please guide me how to solve this issue?


Solution

  • Let suppose language change settings is from MainActivity. And so get Navigation Drawer menu item from NavigationView and initViews() within onCreate().

        Menu menu = navigationView .getMenu();
        View headerView = navigationView.getHeaderView(0);
        txt_nav_header_name = headerView.findViewById(R.id.txt_nav_header_name);
    

    After that we call loadLocale() for language change and update Strings Values within onCreate(). See here:

      public void changeLang(String lang){
        if (lang.equalsIgnoreCase(""))
            return;
        myLocale = new Locale(lang);
        saveLocale(lang);
        Locale.setDefault(myLocale);
        android.content.res.Configuration config = new android.content.res.Configuration();
        config.locale = myLocale;
        getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
        updateTexts();
    }
    
    public void saveLocale(String lang){
        String langPref = "Language";
        SharedPreferences prefs = getSharedPreferences("CommonPrefs", Activity.MODE_PRIVATE);
        SharedPreferences.Editor editor = prefs.edit();
        editor.putString(langPref, lang);
        //  editor.commit();
        editor.apply();
    }
    
    public void loadLocale(){
        String langPref = "Language";
        SharedPreferences prefs = getSharedPreferences("CommonPrefs", Activity.MODE_PRIVATE);
        String language = prefs.getString(langPref, "");
        changeLang(language);
    }
    
    private void updateTexts() {
        languageUpdate();
    }
    
    private void languageUpdate() {
        txt_app_name.setText(getString(R.string.app_name));
        if (actionBar != null){
            actionBar.setTitle(getString(R.string.app_name));
        }
        toolbar.setTitle(getString(R.string.app_name));
    
        txt_nav_header_name.setText(getString(R.string.app_name));
        // txt_nav_header_name.setTypeface(tf_mm); // for embedded font
        for (int i=0;i<menu.size();i++) {
            MenuItem mi = menu.getItem(i);
            int id = mi.getItemId();
            if (id == R.id.nav_home){
                mi.setTitle(getString(R.string.home));
            }
            else if (id == R.id.nav_history){
                mi.setTitle(getString(R.string.history));
            }
            else if (id == R.id.nav_aboutus){
                mi.setTitle(getString(R.string.about));
            }
            else if (id == R.id.nav_guide){
                mi.setTitle(getString(R.string.guide));
            }
            label= new String[] {getString(R.string.farmer), getString(R.string.merchant), getString(R.string.news), getString(R.string.videos)};
            grid.setAdapter(new CustomGrid(this,label,image));
        }
    }
    

    In your onOptionsItemSelected(MenuItem menuItem) method, call language change method. See here:

      @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        String lang;
        if(id == R.id.action_lang_en_settings){
            lang = "en";
            changeLang(lang);
            return true;
        }
        else if(id == R.id.action_lang_mm_settings){
            lang = "my";            
            changeLang(lang);
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
    

    In Fragment or Activity, call loadLocale() and update views in languageUpdate(). I hope this will solve yours.