Android 从共享首选项启动应用时,应用区域设置不会更改

Android App Locale Does Not Get Changed on App Start From Shared Preferences

我的应用通过按下按钮更改区域设置,这与 Intent 刷新配合使用效果很好。 & 一旦按下按钮,区域设置也会进入共享首选项。

我已检查区域设置是否已正确保存并在应用启动时以正确的值检索。

但是,一旦应用程序关闭并再次启动,我认为语言环境发生了变化,片段标题也发生了变化,但侧边导航菜单标题保留在默认语言环境中,这对我来说是英语。 在 Fragments 内部,区域设置已正确更改。

这是我在 onCreate()、onStart() 上尝试过的代码,并且还包含在 MainActivity 扩展 AppCompatActivity.[=13= 的 onResume() 中]

    @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);
}

请告诉我如何纠正我做错的事情。非常感谢!

Launcher Activity 如 Simple UX Apps 所述,但它似乎无法正常工作,除非我再次在此特定代码中做错了。

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();
}
}

创建另一个 activity 作为启动器 activity。

然后在您的清单中声明新的启动器 activity,如下所示:

<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>

将您在新的 LauncherActivity 中设置区域设置的代码。 设置语言环境后,从 LauncherActivity 启动 MainAcitivty。

在弄乱它之后,我无法弄清楚为什么只有抽屉布局没有从正确的语言环境字符串文件中提取资源。

因此,由于在所选语言环境下一切正常,合乎逻辑的做法是在 MainActivity 的 onCreate 中更改抽屉布局项目标题。

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

以下代码段之前和之后的代码与我原来的问题相同。

    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();

& 检索字符串

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;
}

如果有更好的解决方案请告诉我!