强制使用不同的语言环境仅适用于后堆栈中的顶部活动 [英] Forcing a different locale works only for top activity in back stack

查看:50
本文介绍了强制使用不同的语言环境仅适用于后堆栈中的顶部活动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在应用本地化方面遇到了一个小问题:

I got a minor problem about app localization:

情况是这样 - 我已经让我的用户始终使用挪威语的应用程序,而不管系统语言如何.

Here's the case - I have given my users an option to always use the application in Norwegian, regardless of system language.

它在大多数情况下都可以正常工作(我进入设置,选中该框以强制使用挪威语,按返回",之前的活动以挪威语显示 - 同样的事情反过来"),但是- 语言更改似乎只能为我的返回堆栈"中的第一个活动正确更新(重新加载资源).​​

It works just fine for the most part (I go to settings, check the box to force Norwegian, press "back" and the previous activity is displayed in Norwegian - same thing "the other way around"), however - the language change only seems to correctly update (reload resources) for the first activity in my "back stack".

举例说明一个典型的场景:

To illustrate a typical scenario:

用户启动应用程序,并显示主要活动(英文).从那里,他选择了第二个活动(也是英语).然后他进入设置(从第二个活动的菜单中)并设置首选项以强制使用挪威语.

User launches the app, and is presented with the main activity (in English). From there, he selects the second activity (also in English). He then goes into settings (from the menu in the second activity) and sets the preference to force Norwegian.

当他返回时,第二个活动已正确更新并以挪威语显示(到目前为止一切顺利).然而,当他按下后退"键时,再次返回主活动,it仍然显示英文...

When he then navigates back, the second activity is correctly updated and displayed in Norwegian (so far so good). However, when he presses "back" once more to return to the main activity, it is still displayed in English...

如果他返回并再次启动应用程序,则主要活动将以挪威语正确显示...

If he goes back out and launches the app again, the main activity is correctly displayed in Norwegian...

这里有没有聪明人对我应该做什么提出建议?

Are there any bright minds here with a suggestion to what I should do?

每个活动中包含的用于设置显示语言的代码:

Code included in every activity to set the display language:

在onCreate中:Globals.locale_default = Locale.getDefault().getDisplayLanguage();

In onCreate: Globals.locale_default = Locale.getDefault().getDisplayLanguage();

public void onStart() {
    super.onStart();
    forceNorwegian = settings.getBoolean(getString(R.string.pref_key_forceNorwegian).toString(), false);
       if (forceNorwegian) {
           languageCheck("no");
       } else {
            Globals.locale = null;
            languageCheck(Globals.locale_default);
       }
}

public void languageCheck(String lang) {
    Globals.locale = new Locale( lang );
    // Check the current system locale and change it to Norwegian if it's not already the default
    Globals.checkLocale( this );
    if (Globals.language_changed) {
        // Restart activity
        Intent restart = getIntent();
        finish();
        Globals.language_changed = false;
        startActivity(restart);
    }
}

Globals.java:

Globals.java:

public class Globals {

public static Locale locale = null;
    public static String locale_default = null;
    public static boolean language_changed = false;

    public static void checkLocale( Activity a ) {
        if( locale == null )
            return;

        Configuration config = a.getBaseContext().getResources().getConfiguration();
        if( !config.locale.equals( locale ) )
        {  // Change to the new locale.  Everything will need to be closed or reloaded.
            config.locale = locale;
            a.getBaseContext().getResources().updateConfiguration( config, null );
            language_changed = true;
        }
    }
}

推荐答案

问题可能是因为布尔值 Globals.language_changed 是静态的,因此当从顶级活动调用 languageCheck 时,这个布尔值在之前变为 falselanguageCheck 是从后台活动调用的.您可能会进行一些检查以查看层次结构中较早的 Activit(ies) 是否已打开,如果是,则将布尔值设置为 true,以防用户按下后退按钮.另一种选择是在选择新区域设置时立即重新加载所有打开的活动的一些逻辑.

The problem may be coming from the fact that the boolean Globals.language_changed is static, and therefore when languageCheck is called from the top activity, this boolean becomes false before languageCheck is called from the back activity. You might put in some checks to see if Activit(ies) earlier in the hierarchy are open, and if so keep the boolean set as true in case the user presses the Back button. Another option would be some logic that reloads all open Activities at once when the new locale is selected.

-- 编辑--经过进一步检查,我认为这不是您的问题,因为您还在为每个活动更新 onStart 中的布尔值(我第一次阅读时错过了这部分).也许当堆栈中较高的活动之一更改时,区域设置发生了变化,但堆栈中较低的活动只需要刷新.较低活动之一的方向是否将其从英语更改为挪威语?

-- EDIT -- On further examination, I don't think this is quite your problem, since you are also updating the boolean in onStart for each activity (I missed this part when I read it the first time). Perhaps the locale changed when one of the Activities higher in the stack changed it, but the Activities lower in the stack just need to refresh. Does an orientation change on one of the lower Activities change it from English to Norwegian?

-- 编辑 2 --检查这是否是问题的最简单方法是在 Globals.checkLocale 中添加一些日志以查看此条件语句是否为真:

-- EDIT 2 -- The easiest way to check if that is the problem, would be to add some logging into Globals.checkLocale to see whether or not this conditional statement is true:

if( !config.locale.equals( locale ) )

如果事实证明这是问题所在,那么一种可能的解决方案是在每个 Activity 中保存一个本地 Locale 实例而不是全局实例,然后与该实例进行比较.例如,您可以在每个 Activity 的 onCreate 方法中获取一个 Locale 实例:

If that turns out to be the problem, then one possible solution would be to save a local Locale instance in each Activity rather than a global one, and compare to that one. For example, you could grab a Locale instance in each Activity's onCreate method:

myLocale = getBaseContext().getResources().getConfiguration().locale;

然后,不要调用 Globals.checkLocal,只需执行以下条件语句(在每个 Activity 的 languageCheck 方法中):

Then, instead of calling Globals.checkLocal, just do the following conditional statement (in each Activity's languageCheck method):

if( Globals.locale != null && !Globals.locale.equals( myLocale ) )
{
    Configuration config = getBaseContext().getResources().getConfiguration();
    config.locale = Globals.locale;
    getBaseContext().getResources().updateConfiguration( config, null );
    Intent restart = getIntent();
    finish();
    startActivity( restart );
}

重新启动后,Activity 的 onCreate 方法将再次被调用,这会将 myLocale 更新为正确的值.这只是一个快速解决方案,不一定是最好的解决方案.每个活动.

Upon restarting, the Activity's onCreate method would get called again, which would update myLocale to the correct value. This is just a quick solution, not necessarily the best one.. you could expand on this to move some of that code into a method in Globals if you wanted for example, or use a different location than onCreate to get the local Locale instance for each Activity.

这篇关于强制使用不同的语言环境仅适用于后堆栈中的顶部活动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆