【问题标题】:Change the locale at runtime?在运行时更改语言环境?
【发布时间】:2012-10-22 07:43:48
【问题描述】:

我们有一个 Android 应用程序,可用作远程 PC 程序的客户端。我们想添加一个功能,以便 PC 可以指示 Android 应用程序在运行时更改其区域设置,即启动应用程序;将其与 PC 通信;稍后,PC 会告诉应用程序切换到西班牙语或中文。

我们已经为它们各自的语言环境设置了所有布局和字符串资源。我们的应用是用户看到的唯一应用,因此设备的其余部分是否保持英文并不重要。

Change language programmatically in Android 上还有另一个线程,但似乎还没有得出结论。

我可以放。 . .

Locale locale = new Locale(sTheNewLocale);
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config,
      getBaseContext().getResources().getDisplayMetrics());

。 . .在 setContentView() 之前的 onCreate() 中,但如果我想在屏幕启动并运行后更改语言环境,这并没有真正的帮助。有没有办法在 Activity 已经运行后重新加载内容视图?所以是否有任何实用的方法可以可靠地即时更改语言环境,还是我必须告诉我的老板除了在启动应用程序之前将整个设备设置为新的语言环境之外,这是无法做到的?

【问题讨论】:

    标签: android localization


    【解决方案1】:

    从 API 11 开始,您可以使用 recreate,因此可以在您的活动中使用此方法:

    private void restartInLocale(Locale locale)
    {
        Locale.setDefault(locale);
        Configuration config = new Configuration();
        config.locale = locale;
        Resources resources = getResources();
        resources.updateConfiguration(config, resources.getDisplayMetrics());
        recreate();
    }
    

    【讨论】:

    • 方法 updateConfiguration() 已弃用。这是一个未弃用的解决方案:stackoverflow.com/questions/40221711/…
    • config.locale 也被贬值了
    • @HasanAliKaraca 也包含在链接的答案中。
    【解决方案2】:

    您可以启动 Activity 的新实例并退出旧实例。这是一个完整的(未经测试的)示例,您可以如何存储任何所需的语言并重新启动您的应用程序。您只需使用您喜欢的语言致电restartInLanguage。

    public class YourMainActivity extends Activity {
        private static final String APP_SHARED_PREFS = "com.example.test";
        private SharedPreferences settings;
        private Editor editor;
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            settings=getSharedPreferences(APP_SHARED_PREFS, Activity.MODE_PRIVATE);
            editor=settings.edit();
    
            Locale locale = new Locale(settings.getString("lang", "default-lang"));
            Locale.setDefault(locale);
            Configuration config = new Configuration();
            config.locale = locale;
            getResources().updateConfiguration(config, getResources().getDisplayMetrics());
    
            // your stuff...
        }
    
        public void restartInLanguage(String lang) {
            editor.putString("lang", lang);
            editor.commit();
            Intent intent = getIntent();
            finish();
            startActivity(intent);
        }
    
        // ...
    }
    

    【讨论】:

    • 我会从哪里做这个?该程序在主活动中启动,那么这将如何改变主屏幕的区域设置?还是您的意思是从 Main 活动开始一个新的 Main 活动实例,然后让旧的 Main 活动自行终止? (这甚至可以做到吗?)
    • 是的,就是这样...您将上面的代码放在 language changed handler 中,它会重新启动您的主要活动。
    • 我仍然无法解析您的答案。你是说我可以从我的主要活动重新开始我的主要活动吗?我该怎么做?
    • 尝试添加的示例希望对您有所帮助。
    【解决方案3】:

    我结合了@weston 和@rekire(都是+1)并扩展它来处理这个用例:

    • ActivityA => ActivityB => SettingsActivity-changeLocale

    在SettingsActivity 中的changeLocale 之后,还应重新创建父活动ActivityA 和ActivityB 以反映新的语言环境。

    我的解决方案:ActivityA 和 ActivityB 继承自 LocalizedActivity,如果语言环境发生变化,它将检查 onResume,并在必要时触发 recreate()

    因此,从 LocalizedActivity 继承的每个活动都会自动处理特定于应用的区域设置更改。

    /**
     * An activity that can change the locale (language) of its content.
     *
     * Inspired by http://stackoverflow.com/questions/13181847/change-the-locale-at-runtime
     *
     * Created by k3b on 07.01.2016.
     */
    public class LocalizedActivity extends Activity {
        /** if myLocale != Locale.Default : activity must be recreated in on resume */
        private Locale myLocale = null;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            fixLocale(this);
            super.onCreate(savedInstanceState);
        }
    
        @Override
        protected void onResume() {
            super.onResume();
    
            // Locale has changed by other Activity ?
            if ((myLocale != null) && (myLocale.getLanguage() != Locale.getDefault().getLanguage())) {
                myLocale = null;
                recreate();
            }
        }
    
        /**
         * Set Activity-s locale to SharedPreferences-setting.
         * Must be called before onCreate
         * @param context
         */
        public static void fixLocale(Context context)
        {
            final SharedPreferences prefs = PreferenceManager
                    .getDefaultSharedPreferences(context);
            String language = prefs.getString(Global.PREF_KEY_USER_LOCALE, "");
            Locale locale = Global.systemLocale; // in case that setting=="use android-locale"
            if ((language != null) && (!language.isEmpty())) {
                locale = new Locale(language); // overwrite "use android-locale"
            }
    
            if (locale != null) {
                Locale.setDefault(locale);
                Configuration config = new Configuration();
                config.locale = locale;
                Resources resources = context.getResources();
                resources.updateConfiguration(config, resources.getDisplayMetrics());
                // recreate();
    
                if (context instanceof LocalizedActivity) {
                    ((LocalizedActivity) context).myLocale = locale;
                }
            }
        }
    }
    

    这是我的A Photo Manager project中使用的LocalizedActivity.java和SettingsActivity.java的来源

    【讨论】:

      【解决方案4】:

      解决方案是在设置语言环境后,在 onResume 方法的每个活动中使用 setContentView 和 controlLanguage(您也可以从 Global 类调用此方法)方法。 示例:

      @Override
          public void onClick(View v) {
              SharedPreferences.Editor editor;
              editor = sharedPref.edit();
              Configuration config = new Configuration(getBaseContext().getResources().getConfiguration());
              String language = "";
              switch (v.getId()){
                  case R.id.turkceButton:
                      editor.putString("language", "tr");
                      language="tr";
                      break;
                  case R.id.englishButton:
                      editor.putString("language", "en");
                      language="en";
                      break;
              }
              Locale locale = new Locale(language);
              Locale.setDefault(locale);
              config.locale = locale;
              getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
              editor.commit();
      
      
      @Override
          protected void onResume() {
              super.onResume();
              controlLanguage(getApplicationContext(), getResources());
              setContentView(R.layout.main);
          }
      
      public void controlLanguage(Context context, Resources res){
              SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(context);
              String language = sharedPref.getString("language","en");
              Locale locale = new Locale(language);
              Locale.setDefault(locale);
              res.getConfiguration().locale = locale;
              res.updateConfiguration(res.getConfiguration(), res.getDisplayMetrics());
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-01-21
        • 1970-01-01
        相关资源
        最近更新 更多