区域设置:未调用onConfigurationChanged

Big*_*igT 6 android locale android-manifest android-fragments

我希望我的语言动态更改,我正在尝试使用onConfigurationChanged但它没有被调用.我有一个MainActivity,可以创建我的操作栏和viewpager.我的其余页面都是碎片.在我的SettingsFragment中,我有一个按钮可以将语言切换为法语.

langChange.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View vi) {
            MainActivity main = (MainActivity)getActivity();
            main.langChange();
        }

});
Run Code Online (Sandbox Code Playgroud)

然后在我的MainActivity中

@Override
public void onConfigurationChanged(Configuration newConfig){
    super.onConfigurationChanged(newConfig);
    if (locale != null){
        newConfig.locale = locale;
        Locale.setDefault(locale);
        getBaseContext().getResources().updateConfiguration(newConfig, getBaseContext().getResources().getDisplayMetrics());
    }
}

public void langChange(){
    if(currentLanguage == FRENCH_LANGUAGE){
        locale = new Locale("en");
        Locale.setDefault(locale);
        Configuration c = getBaseContext().getResources().getConfiguration();
        c.locale = locale;
        getBaseContext().getResources().updateConfiguration(c,getBaseContext().getResources().getDisplayMetrics());
        currentLanguage = "English";
    }
    else if(currentLanguage == ENGLISH_LANGUAGE){
        locale = new Locale("fr");
        Locale.setDefault(locale);
        Configuration c = getBaseContext().getResources().getConfiguration();
        c.locale = locale;
        getBaseContext().getResources().updateConfiguration(c,getBaseContext().getResources().getDisplayMetrics());
        currentLanguage = "French";
    }
    actionBar.setSelectedNavigationItem(actionBar.getTabCount() - 1); //This just puts it back to the settings tab
}
Run Code Online (Sandbox Code Playgroud)

onConfigurationChanged不会被调用.在我的清单中我有:

<activity android:name="MainActivity" android:screenOrientation="portrait" android:configChanges="locale"></activity>
Run Code Online (Sandbox Code Playgroud)

我试过添加一个或所有这些选项但orientation|keyboardHidden|screenSize没有成功.

所有这一切的原因是因为我想在单击按钮后更改actionBar文本和所有其他文本.我有一个单独的法语字符串文件.

任何帮助都会很棒.

Ale*_*x.F 7

你必须定义android:configChanges ="layoutDirection | locale"才能调用onConfigurationChanged().

  • 他是完全正确的,添加`layoutDirection`工作,没有没有. (4认同)

Dar*_*ind 4

好的,我已经对此进行了一些研究。

我不确定为什么onConfigurationChanged不调用该方法,所以我希望有人能够在这方面启发我们。

在我的搜索中,我偶然发现了本教程,它实际上Locale通过更改配置来更改。

您的代码实际上看起来很像本教程;-)

无论如何,本教程和代码的重要之处在于这个方法:

private void updateTexts() {
    txt_hello.setText(R.string.hello_world);
    btn_en.setText(R.string.btn_en);
    btn_ru.setText(R.string.btn_ru);
    btn_fr.setText(R.string.btn_fr);
    btn_de.setText(R.string.btn_de);
}
Run Code Online (Sandbox Code Playgroud)

这就是“魔法”发生的地方;更改区域设置后,您将需要重新加载资源,并且由于您告诉 Android 您想要自己处理一些配置,因此您需要通过再次设置 UI 项目文本来专门重新加载所有文本。

完成后,应用程序将从特定区域设置文件夹加载字符串。

Android为什么会这样,可以在官方文档中找到这样的Activity说法:

[...]

这样做是因为任何应用程序资源(包括布局文件)都可以根据任何配置值进行更改。因此,处理配置更改的唯一安全方法是重新检索所有资源,包括布局、可绘制对象和字符串。由于活动必须已经知道如何保存其状态并从该状态重新创建自己,因此这是让活动使用新配置重新启动的便捷方法。

编写教程的人很友善地添加了整个教程项目作为下载,所以我建议您去检查一下它是如何工作的,因为它正在工作;-) 您可以评论该方法onConfigurationChanged,因为它没有似乎在做任何事情。

希望这可以帮助。