4

我遇到了一个关于应用本地化的小问题:

情况就是这样——我为我的用户提供了一个选项,无论系统语言如何,我都可以始终以挪威语使用该应用程序。

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

举例说明一个典型场景:

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

然后当他导航回来时,第二个活动被正确更新并以挪威语显示(到目前为止一切都很好)。但是,当他再次按“返回”返回主活动时,仍然显示为英文......

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

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

相关源代码:

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

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

全局.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;
        }
    }
}
4

2 回答 2

1

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

--编辑-- 进一步检查,我认为这不是你的问题,因为你也在为每个活动更新 onStart 中的布尔值(我第一次阅读时错过了这部分)。当堆栈中较高的活动之一更改它时,可能会更改语言环境,但堆栈中较低的活动只需要刷新。较低活动之一的方向更改是否将其从英语更改为挪威语?

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

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

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

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

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

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 更新为正确的值。这只是一个快速的解决方案,不一定是最好的解决方案。例如,如果需要,您可以扩展它以将一些代码移动到 Globals 中的方法中,或者使用与 onCreate 不同的位置来获取本地 Locale 实例每个活动。

于 2012-07-29T14:28:07.790 回答
0

我认为它的线

  Configuration config = a.getBaseContext().getResources().getConfiguration();

getBaseContext()只会让您从另一个 Acitivty 内部获得对 Activity 的引用。因此,这就是为什么当您返回到前一个 Activity 而不是主应用程序时,它会反映更改

使用getApplicationConext()它来反映整个应用程序的变化。这会将更改与应用程序的整个生命周期联系起来,因此应用程序中的每个 Activity

于 2012-07-29T01:48:37.980 回答