Change app language programmatically in Android

前端 未结 30 3055
面向向阳花
面向向阳花 2020-11-21 04:34

Is it possible to change the language of an app programmatically while still using Android resources?

If not, is it possible to request a resource in an specific lan

相关标签:
30条回答
  • This is working when i press button to change text language of my TextView.(strings.xml in values-de folder)

    String languageToLoad = "de"; // your language
    Configuration config = getBaseContext().getResources().getConfiguration();
    Locale locale = new Locale(languageToLoad);
    Locale.setDefault(locale);
    config.locale = locale;
    getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
    recreate();
    
    0 讨论(0)
  • 2020-11-21 05:13

    There are some steps that you should implement

    First, you need to change the locale of your configuration

    Resources resources = context.getResources();
    
    Configuration configuration = resources.getConfiguration();
    configuration.locale = new Locale(language);
    
    resources.updateConfiguration(configuration, resources.getDisplayMetrics());
    

    Second, if you want your changes to apply directly to the layout that is visible, you either can update the views directly or you can just call activity.recreate() to restart the current activity.

    And also you have to persist your changes because after user closes your application then you would lose the language change.

    I explained more detailed solution on my blog post Change Language Programmatically in Android

    Basically, you just call LocaleHelper.onCreate() on your application class and if you want to change locale on the fly you can call LocaleHelper.setLocale()

    0 讨论(0)
  • 2020-11-21 05:15

    similar to the accepted answered but 2017 version and added restart (without restarting, sometimes the next Activity still renders English):

    // Inside some activity...
    private void changeDisplayLanguage(String langCode) {
    // Step 1. Change the locale in the app's configuration
        Resources res = getResources();
        android.content.res.Configuration conf = res.getConfiguration();
        conf.setLocale(currentLocale);
        createConfigurationContext(conf);
    // Step 2. IMPORTANT! you must restart the app to make sure it works 100%
        restart();
    }
    private void restart() {
        PackageManager packageManager = getPackageManager();
        Intent intent = packageManager.getLaunchIntentForPackage(getPackageName());
        ComponentName componentName = intent.getComponent();
        Intent mainIntent = IntentCompat.makeRestartActivityTask(componentName);
        mainIntent.putExtra("app_restarting", true);
        PrefUtils.putBoolean("app_restarting", true);
        startActivity(mainIntent);
        System.exit(0);
    }
    
    0 讨论(0)
  • 2020-11-21 05:16

    This code really works:

    fa = Persian, en = English

    Enter your language code in languageToLoad variable:

    import android.app.Activity;
    import android.content.res.Configuration;
    import android.os.Bundle;
    
    public class Main extends Activity {
      /** Called when the activity is first created. */
      @Override
      public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        String languageToLoad  = "fa"; // your language
        Locale locale = new Locale(languageToLoad); 
        Locale.setDefault(locale);
        Configuration config = new Configuration();
        config.locale = locale;
        getBaseContext().getResources().updateConfiguration(config, 
          getBaseContext().getResources().getDisplayMetrics());
        this.setContentView(R.layout.main);
      }
    }
    
    0 讨论(0)
  • 2020-11-21 05:18

    Here is some code that works for me:

    public class  MainActivity extends AppCompatActivity {
        public static String storeLang;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
    
            SharedPreferences shp = PreferenceManager.getDefaultSharedPreferences(this);
            storeLang = shp.getString(getString(R.string.key_lang), "");
    
            // Create a new Locale object
            Locale locale = new Locale(storeLang);
    
            // Create a new configuration object
            Configuration config = new Configuration();
            // Set the locale of the new configuration
            config.locale = locale;
            // Update the configuration of the Accplication context
            getResources().updateConfiguration(
                    config,
                    getResources().getDisplayMetrics()
            );
    
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
        }
    }
    

    Source: here

    0 讨论(0)
  • 2020-11-21 05:18

    I finally figured out how to setup it to work on both =N android versions.

    Extend AppCompatActivity with your own abstract class, like:

    abstract class MLAppCompatActivity : AppCompatActivity() {
      override fun attachBaseContext(newBase: Context?) {
        super.attachBaseContext(LocaleHelper.wrap(newBase))
      }
    
      override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
            LocaleHelper.wrap(this)
        }
      }
    }
    

    attachBaseContext is called on Android >=N versions and on this way activity will use the correct context. On Android <N, we have to call this function on one other way, before setting content view. Therefore we override onCreate function to set correct context. Means, whenever you create a new Activity you have to extend your abstract class. Like this one:

    class TermsActivity : MLAppCompatActivity() {
      override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_terms)
      }
    }
    

    And finally the LocaleHelper is like this:

    import android.annotation.TargetApi;
    import android.content.Context;
    import android.content.ContextWrapper;
    import android.content.SharedPreferences;
    import android.content.res.Configuration;
    import android.content.res.Resources;
    import android.os.Build;
    import android.util.DisplayMetrics;
    
    import com.at_zone.constants.SharedPreferencesKeys;
    
    import java.util.Locale;
    
    public class LocaleHelper extends ContextWrapper {
    
        public LocaleHelper(Context base) {
            super(base);
        }
    
        public static Context wrap(Context context) {
            SharedPreferences sharedPreferences = context.getSharedPreferences(
                    SharedPreferencesKeys.SHARED_PREFERENCES, Context.MODE_PRIVATE
            );
            String language = sharedPreferences.getString(SharedPreferencesKeys.CURRENT_LANGUAGE, "default");
            if (!language.equals("default")) {
                Configuration config = context.getResources().getConfiguration();
                if (!language.equals("")) {
                    Locale locale = new Locale(language);
                    Locale.setDefault(locale);
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                        setSystemLocale(config, locale);
                    } else {
                        setSystemLocaleLegacy(context, config, locale);
                    }
                    config.setLayoutDirection(locale);
                    context = context.createConfigurationContext(config);
                }
                return new LocaleHelper(context);
            }
            return context;
        }
    
        public static String getSystemLanguage(Context context) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                return getSystemLocale(context).getLanguage().toLowerCase();
            } else {
                return getSystemLocaleLegacy(context).getLanguage().toLowerCase();
            }
        }
    
        public static Locale getSystemLocaleLegacy(Context context) {
            Configuration config = context.getResources().getConfiguration();
            return config.locale;
        }
    
        @TargetApi(Build.VERSION_CODES.N)
        public static Locale getSystemLocale(Context context) {
            return context.getResources().getConfiguration().getLocales().get(0);
        }
    
        public static void setSystemLocaleLegacy(Context context, Configuration config, Locale locale) {
            config.locale = locale;
            Resources res = context.getResources();
            DisplayMetrics dm = res.getDisplayMetrics();
            res.updateConfiguration(config, dm);
        }
    
        @TargetApi(Build.VERSION_CODES.N)
        public static void setSystemLocale(Configuration config, Locale locale) {
            config.setLocale(locale);
        }
    
    }
    
    0 讨论(0)
提交回复
热议问题