Android旋转后语言更改

8
当我的应用程序被安装后,在第一次运行时会要求用户选择语言;但是如果用户在第二次开始使用应用程序,则语言会自动设置为先前选择的语言。
问题是,在第一次运行时,用户选择语言后,应用程序仍然是英文的(无论用户选择了哪种语言),但是如果我旋转设备,那么语言就会改变为正确的语言(选择的语言)。在应用程序第二次运行时,同样的问题也会发生; 应用程序以英语启动,但旋转后语言会更改为正确的语言。
有什么建议吗?谢谢您提前的帮助。
这里是来自MainActivity的代码,我正在更改语言:
private void initApp() {
        if (Settings.getLanguage().equals("")){ 
            String[] items = { getResources().getString(R.string.lang_eng), getResources().getString(R.string.lang_geo)};
            showDialogSingleChoise(items, getResources().getString(R.string.select_language_title), 0, false, false, this.languageSelectedListener, this.languageConfirmedListener, null);
        } else {        
            System.out.println("initApp: " + Settings.getLanguage());

            Settings.setLanguage(MainActivity.this.getResources(), Settings.getLanguage());
            appVersionCheck();
        }
    }

private OnClickListener languageConfirmedListener = new OnClickListener() {

    @Override
    public void onClick(DialogInterface dialog, int which) {
        Settings.setLanguage(MainActivity.this.getResources(), MainActivity.this.language);
        appVersionCheck();
    }
};

这里是从设置中的代码片段:

public static void setLanguage(Resources res, String langString){
        System.out.println("lang in pref: " + langString);
        setStringProperty(PREFS_LANG ,langString);
        MainApp.getInstance().setLocale(res);
    }

这是我的Application类:

public class MainApp extends Application {
    private static volatile MainApp instance;

    public static MainApp getInstance() {
        return MainApp.instance;
    }

    @Override
    public void onCreate() {
        MainApp.instance = this;
        super.onCreate();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        setLocale(this.getResources());
    }

    public void setLocale(Resources res) {
        System.out.println("initApp: " + Settings.getLanguage() == "" ? Settings.LANG_EN : Settings.getLanguage());
        Configuration conf = res.getConfiguration();
        conf.locale = new Locale(Settings.getLanguage() == "" ? Settings.LANG_EN : Settings.getLanguage());
        res.updateConfiguration(conf, res.getDisplayMetrics());
    }
}

最后,这是AndroidManifest(我是否需要添加android:configChanges="locale"?):

<application
        android:name="...MainApp"
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="....MainActivity"
            android:configChanges="locale"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

你是否使用不同的字符串文件来处理不同语言,且使用首选值文件夹名称,例如 values-fr 用于法语? - H Raval
不需要调用onConfigurationChanged()...在我的应用程序中,我只是使用了Resources resources = getResources(); Configuration configuration = resources.getConfiguration(); configuration.locale = new Locale("en"); resources.updateConfiguration(configuration,dm); 对我来说完美运行。 - H Raval
3个回答

3

在更改语言环境后,您的配置不能立即应用,需要重新启动Activity。当您旋转屏幕时,Activity将重新启动并应用配置更改。

在单击更改语言环境后,您应该手动重新启动Activity,以下是重新启动Activity的代码示例:

private void restartActivity() {
    Intent intent = getIntent();
    finish();
    startActivity(intent);
    }

我认为你不应该在你的Application类中编写更改语言环境的代码,而应该在你用于更改语言环境的Activity中编写。
至于在未来打开应用程序时应用新的语言环境,您可以使用SharedPreferences保存您的配置,并在每次打开应用程序时获取语言环境值并应用它。
您可以在Application类的onCreate()方法中获取SharedPreferences并应用语言环境。
当然,您应该在清单文件中编写android:configChanges="locale|orientation",并且onConfigurationChanged()方法也是必要的。因为如果您旋转屏幕或执行其他更改系统配置的操作,则可以重新启动Activity,将应用默认语言环境。因此,您应确保在每次更改配置时都应用新的语言环境。
有关如何处理语言环境更改的详细信息,请阅读此文档:如何在应用程序内更改语言(Locale)后刷新活动

这个解决方案对我没用。问题是finish和startActivity之间存在竞争条件。如果startActivity先发生,语言在旋转屏幕之前不会改变。我的解决方案是设置一个shouldRestartAfterDestroy属性为true,然后调用finish。在activity的onDestroy中,如果shouldRestartAfterDestroy == true,则调用startActivity。 - MkSMC

1

我在应用程序中覆盖了ConfigChange,并且每次调用configurationChanged时都会调用setLocale函数,代码如下:

public class AioApplication extends Application {

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        setLocale(LocaleUtility.getLocale());
    }

    @Override
    public void onCreate() {
        super.onCreate();

        LocaleUtility.initialize(this);
    }



    private void setLocale(Locale locale) {
        Configuration conf = getBaseContext().getResources().getConfiguration();
        conf.locale = locale;
        getBaseContext().getResources().updateConfiguration(conf, getResources().getDisplayMetrics());
        Configuration systemConf = Resources.getSystem().getConfiguration();
        systemConf.locale = locale;
        Resources.getSystem().updateConfiguration(systemConf, Resources.getSystem().getDisplayMetrics());
        Locale.setDefault(locale);
    }

}

0

看起来你的setLocale更新了应用程序的配置。但是你已经要求使用android:configChanges="locale"手动处理该配置更改。

如果你删除那行,你的配置更改可能会生效。

我认为你可以从应用程序对象中删除onConfigurationChange方法。这不会导致当前进入无限循环吗?

更新:看起来手动更改语言环境配置不会导致活动重新启动。看看这个:在应用程序内部更改语言环境。虽然如果可以的话,我会非常小心地使用android:configChanges


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接