java - 所有 Activity 中的语言都不会改变

标签 java android android-preferences

我正在开发和应用多项 Activity 。其中之一是“设置” Activity ,它可以选择更改应用程序语言。

以下是我在“设置” Activity 中处理更改语言的方法:

final ListPreference language = (ListPreference) findPreference("language");
    language.setSummary(Utils.getStringPreferences(context, "not-found", "language", Utils.USER_PREFS));
    language.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
        @Override
        public boolean onPreferenceChange(Preference preference, Object newValue) {
            if (newValue.toString().equals("English"))
                Utils.setStringPreferences(context, "English", "language", Utils.USER_PREFS);
            else if (newValue.toString().equals("Español"))
                Utils.setStringPreferences(context, "Español", "language", Utils.USER_PREFS);
            analysis_performance.setSummary(newValue.toString());
            restartActivity();
            return false;
        }
    });

这是我用来更改语言的函数,在“setContentView(R.layout.layout);”之前的所有 Activity 中调用方法:

public static void updateLanguage(Context context) {
    String language = getStringPreferences(context, "not-found", "language", USER_PREFS);
    String country = null;
    if (!"not-found".equals(language)) {
        if ("English".equals(language)) {
            language = "en";
            country = "US";
        } else if ("Español".equals(language)) {
            language = "es";
            country = "ES";
        }
        Locale locale = new Locale(language, country);
        Locale.setDefault(locale);
        Configuration config = new Configuration();
        config.locale = locale;
        context.getResources().updateConfiguration(config, null);
    }
}

显然它有效,但仅适用于某些 Activity 。如果我想让所有 Activity 都具有相同的语言,我必须在使用上述功能后重新启动应用程序。

这是 Activity 之间的导航:

- MainActivity
    - Settings
        - Activity_1
    - Activity_2

Activity 正确更改了语言:Activity_1 和 Activity_2

Activity 未更改语言:MainActivity 和设置

设置 Activity :

Context context;

private AppCompatDelegate mDelegate;

List<String> allLaunchers;
List<String> allLaunchersPackages;
BrowserSpinnerAdapter adapter;

private final String TAG = Settings.class.getSimpleName();

Resources res;

@Override
protected void onCreate(Bundle savedInstanceState) {
    getDelegate().installViewFactory();
    getDelegate().onCreate(savedInstanceState);
    super.onCreate(savedInstanceState);
    Utils.updateLanguage(this);
    setContentView(R.layout.activity_settings);
    setSupportActionBar((Toolbar) findViewById(R.id.toolbar));

    addPreferencesFromResource(R.xml.settings);

    context = this;
    res = getResources();

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    // Display navigation button
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);

    final ListPreference browser_selection = (ListPreference) findPreference("browser_analysis");
    fillBrowserSelection();
    browser_selection.setSummary(allLaunchers.get(allLaunchersPackages.indexOf(Utils.getStringPreferences(context, "not-found", "browser", Utils.USER_PREFS))));
    browser_selection.setEntries(allLaunchers.toArray(new CharSequence[allLaunchers.size()]));
    browser_selection.setEntryValues(allLaunchersPackages.toArray(new CharSequence[allLaunchersPackages.size()]));
    browser_selection.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
        @Override
        public boolean onPreferenceChange(Preference preference, Object newValue) {
            Utils.setStringPreferences(context, newValue.toString(), "browser", Utils.USER_PREFS);
            browser_selection.setSummary(allLaunchers.get(allLaunchersPackages.indexOf(newValue.toString())));
            return false;
        }
    });

    final ListPreference security_level = (ListPreference) findPreference("security_level");
    security_level.setSummary(Utils.getIntPreferences(context, -1, "security_level", Utils.USER_PREFS)+"");
    security_level.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
        @Override
        public boolean onPreferenceChange(Preference preference, Object newValue) {
            Utils.setIntPreferences(context, Integer.parseInt(newValue.toString()), "security_level", Utils.USER_PREFS);
            security_level.setSummary(newValue.toString());
            return false;
        }
    });

    final ListPreference analysis_performance = (ListPreference) findPreference("performance");
    analysis_performance.setSummary(Utils.getStringPreferences(context, "not-found", "performance", Utils.USER_PREFS));
    analysis_performance.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
        @Override
        public boolean onPreferenceChange(Preference preference, Object newValue) {
            Utils.setStringPreferences(context, newValue.toString(), "performance", Utils.USER_PREFS);
            analysis_performance.setSummary(newValue.toString());
            return false;
        }
    });

    final ListPreference language = (ListPreference) findPreference("language");
    language.setSummary(Utils.getStringPreferences(context, "not-found", "language", Utils.USER_PREFS));
    language.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
        @Override
        public boolean onPreferenceChange(Preference preference, Object newValue) {
            if (newValue.toString().equals("English"))
                Utils.setStringPreferences(context, "English", "language", Utils.USER_PREFS);
            else if (newValue.toString().equals("Español"))
                Utils.setStringPreferences(context, "Español", "language", Utils.USER_PREFS);
            language.setSummary(newValue.toString());
            Utils.updateLanguage(Settings.this);

            recreate();
            return false;
        }
    });
}

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);

    Log.i(TAG, "onConfigurationChanged");

    getBaseContext().getResources().updateConfiguration(newConfig, getBaseContext().getResources().getDisplayMetrics());
    setContentView(R.layout.activity_settings);
    setTitle(R.string.title_activity_settings);

    // Checks the active language
    if (newConfig.locale == Locale.ENGLISH) {
        Toast.makeText(this, "English", Toast.LENGTH_SHORT).show();
    }
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case android.R.id.home:
            onBackPressed();
            return true;
    }
    return super.onOptionsItemSelected(item);
}

public ActionBar getSupportActionBar() {
    return getDelegate().getSupportActionBar();
}

@Override
protected void onPostCreate(Bundle savedInstanceState) {
    super.onPostCreate(savedInstanceState);
    getDelegate().onPostCreate(savedInstanceState);
}

@Override
public void setContentView(@LayoutRes int layoutResID) {
    getDelegate().setContentView(layoutResID);
}

@Override
protected void onPostResume() {
    super.onPostResume();
    getDelegate().onPostResume();
}

@Override
protected void onStop() {
    super.onStop();
    getDelegate().onStop();
}

@Override
protected void onDestroy() {
    super.onDestroy();
    getDelegate().onDestroy();
}

private void setSupportActionBar(@Nullable Toolbar toolbar) {
    getDelegate().setSupportActionBar(toolbar);
}

private AppCompatDelegate getDelegate() {
    if (mDelegate == null) {
        mDelegate = AppCompatDelegate.create(this, null);
    }
    return mDelegate;
}

解决方案!!!

在与 Rasi 聊天后,我们最终通过创建此方法来填充布局组件来解决这个问题,正如他在选项 1 中建议的那样(选项 2 也是解决此问题的一种方法,但我更喜欢这种方式,因此用户不会'不必在应用程序中导航):

private void fillSettings() {

    setContentView(R.layout.activity_settings);
    setTitle(R.string.title_activity_settings);

    setPreferenceScreen(null);
    addPreferencesFromResource(R.xml.settings);

    context = this;
    res = getResources();

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    // Display navigation button
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);

    final ListPreference browser_selection = (ListPreference) findPreference("browser_analysis");
    fillBrowserSelection();
    browser_selection.setSummary(allLaunchers.get(allLaunchersPackages.indexOf(Utils.getStringPreferences(context, "not-found", "browser", Utils.USER_PREFS))));
    browser_selection.setEntries(allLaunchers.toArray(new CharSequence[allLaunchers.size()]));
    browser_selection.setEntryValues(allLaunchersPackages.toArray(new CharSequence[allLaunchersPackages.size()]));
    browser_selection.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
        @Override
        public boolean onPreferenceChange(Preference preference, Object newValue) {
            Utils.setStringPreferences(context, newValue.toString(), "browser", Utils.USER_PREFS);
            browser_selection.setSummary(allLaunchers.get(allLaunchersPackages.indexOf(newValue.toString())));
            return false;
        }
    });

    final ListPreference security_level = (ListPreference) findPreference("security_level");
    security_level.setSummary(Utils.getIntPreferences(context, -1, "security_level", Utils.USER_PREFS)+"");
    security_level.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
        @Override
        public boolean onPreferenceChange(Preference preference, Object newValue) {
            Utils.setIntPreferences(context, Integer.parseInt(newValue.toString()), "security_level", Utils.USER_PREFS);
            security_level.setSummary(newValue.toString());
            return false;
        }
    });

    final ListPreference analysis_performance = (ListPreference) findPreference("performance");
    performance = Utils.getStringPreferences(context, "not-found", "performance", Utils.USER_PREFS);
    if (performance.equals(Utils.FOREGROUND)) analysis_performance.setSummary(res.getString(R.string.text_foreground));
    else if (performance.equals(Utils.BACKGROUND)) analysis_performance.setSummary(res.getString(R.string.text_background));
    analysis_performance.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
        @Override
        public boolean onPreferenceChange(Preference preference, Object newValue) {
            if (newValue.equals(res.getString(R.string.text_foreground))) performance = Utils.FOREGROUND;
            else if (newValue.equals(res.getString(R.string.text_background))) performance = Utils.BACKGROUND;
            Utils.setStringPreferences(context, performance, "performance", Utils.USER_PREFS);
            Log.i(TAG, performance);
            analysis_performance.setSummary(newValue.toString());
            return false;
        }
    });

    final ListPreference language = (ListPreference) findPreference("language");
    language.setSummary(Utils.getStringPreferences(context, "not-found", "language", Utils.USER_PREFS));
    language.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
        @Override
        public boolean onPreferenceChange(Preference preference, Object newValue) {
            if (newValue.toString().equals("English"))
                Utils.setStringPreferences(context, "English", "language", Utils.USER_PREFS);
            else if (newValue.toString().equals("Español"))
                Utils.setStringPreferences(context, "Español", "language", Utils.USER_PREFS);
            language.setSummary(newValue.toString());
            updateLanguage(Settings.this);
            fillSettings();
            return false;
        }
    });


}

并在“onCreate”中使用它,如下所示:

@Override
protected void onCreate(Bundle savedInstanceState) {
    getDelegate().installViewFactory();
    getDelegate().onCreate(savedInstanceState);
    super.onCreate(savedInstanceState);
    fillSettings();
}

最佳答案

您已在 onCreate() 方法中编写代码来更改语言。因此,如果您在更改语言后返回 MainActivitySettingsActivity ,它将不会反射(reflect)出来,因为 onCreate() 永远不会调用其中的 Activity 来自堆栈。您必须利用 ActivityonResume() 方法。

但是您仍然无法在 UI 上看到更改后的值,因为 View 已经绘制在屏幕上。现在根据我的说法,你有两个选择 -

  1. 检查onResume()中的语言环境更改,并重新绘制 View 或再次初始化字符串资源。确保直接从正在更改区域设置的 Activity 调用方法,因为 onResume() 不会调用该 Activity
  2. 将用户移至初始屏幕并使用新区域设置启动您的应用程序。在这种情况下,onCreate() 将起作用。
  3. 您可以重写onConfigurationChanged()并检查区域设置是否已更改。如果区域设置发生更改,则重新加载新字符串。

关于java - 所有 Activity 中的语言都不会改变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44085486/

相关文章:

java - 帮助设置和 Android 动态壁纸

android - PreferenceFragment 已弃用

java - 使用构造函数初始化静态字段是否总是被认为是不好的做法?

Java 获取方法 "class not found"

java - 有没有办法通过媒体存储访问应用程序特定的外部存储文件夹?

java - s ParseUser.CurrentUser() 在来自客户端的 Parses 服务器上不同

android - 尝试跨 Windows 机器和 Ubuntu 机器同步 Eclipse 工作区文件时出错;哪些文件必须或不能包含?

java - 强制重新加载 IntelliJ 中的环境变量...无需重新启动?

java - ClassCastException 使用 Class.cast 使用泛型

android - 自制图标字体在移动浏览器上呈现带有图标字形的字符