gpt4 book ai didi

Android 在第二次更改区域设置后从默认字符串文件 (strings.xml) 加载值

转载 作者:行者123 更新时间:2023-11-29 23:22:39 25 4
gpt4 key购买 nike

我正在开发一个 Android 应用程序,我可以通过一个按钮在主屏幕上更改区域设置(英语到阿拉伯语)。它在主屏幕上运行良好,但当我多次更改语言时出现问题。按照以下步骤重新生成:

  • 在主(登录)屏幕上,当前语言是英语,我将其更改为阿拉伯语。 (工作正常)
  • 转到注册或忘记密码页面,现在更改语言。 (阿拉伯语)
  • 返回主屏幕并将语言环境从 Arabic 更改回 English。 (在登录屏幕上工作)
  • 转到注册页面,现在方向已更改,但字符串是从阿拉伯语加载的。 (当前语言是English)

这是我更改语言环境的代码。

import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.preference.PreferenceManager;
import android.support.v4.text.TextUtilsCompat;
import android.support.v4.view.ViewCompat;
import android.view.View;

import java.util.Locale;

public class LocaleSettings {

public static final String LANGUAGE_ENGLISH = "en";
public static final String LANGUAGE_ARABIC = "ar";
public static final String CURRENT_LANGUAGE = "currentLanguage";

/**
* Loads the current language of application
*
* @param context current context, pass "this" for current view context
*/
public static void loadLocal(Context context) {
setLocal(context, PreferenceManager.getDefaultSharedPreferences(context).getString(CURRENT_LANGUAGE, ""));
}

/**
* This fucntion sets the application language
*
* @param context - current context. pass "this" for current view context
* @param lang Language String, i.e. "en" or "ar"
*/
public static void setLocal(Context context, String lang) {
Locale locale = new Locale(lang);
Locale.setDefault(locale);
Configuration config = new Configuration();
config.setLocale(locale);
context.getResources().updateConfiguration(config, context.getResources().getDisplayMetrics());

SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor = pref.edit();
editor.putString(CURRENT_LANGUAGE, lang);
editor.apply();
editor.commit();
}

/**
* Use to change application language using current context
*
* @param context pass "this" for current view context
*/
public static void switchLanguage(Context context) {
if (getCurrentLanguage(context).equals(LANGUAGE_ENGLISH))
setLocal(context, LANGUAGE_ARABIC);
else
setLocal(context, LANGUAGE_ENGLISH);
}

/**
* Get application current active language
*
* @param context pass "this" for current view context
* @return String - language string i.e. en or ar
*/
public static String getCurrentLanguage(Context context) {
return PreferenceManager.getDefaultSharedPreferences(context).getString(CURRENT_LANGUAGE, "");
}

public static boolean isRTL(String locale) {
return TextUtilsCompat.getLayoutDirectionFromLocale(new Locale(locale)) == ViewCompat.LAYOUT_DIRECTION_RTL ? true : false;
}

public static void enforceDirectionIfRTL(Context context){
if(isRTL(getCurrentLanguage(context))){
((Activity) context).getWindow().getDecorView().setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
}

}

这是登录 Activity 的代码

public class LoginActivity extends AppCompatActivity {

private Button loginButton = null;
private EditText account_no = null;
private EditText password = null;
final UserApi userApi = JoezdanServiceGenerator.createService(UserApi.class);

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LocaleSettings.loadLocal(this);
setContentView(R.layout.activity_login);

configureLanaguageButton();

}

private void configureLanaguageButton() {

final ImageButton selectLocale = (ImageButton) findViewById(R.id.btnSelectLanguage);
selectLocale.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
LocaleSettings.switchLanguage(LoginActivity.this);
recreate();
}
});

}

... eliminating irrelevant code
}

这是我的第一个安卓应用,如有错误请见谅。提前致谢。

最佳答案

来自 Android 文档:

Android by default uses the locale of the device to select the appropriate language dependent resources. And most of the time this behaviour is enough for common applications.

在内部更改语言是一个异常(exception)。

首先请阅读this documentation并承认设计的缺陷。

总而言之,这里有两件事我想提一下:

  1. updateConfiguration 已弃用,因此我们需要另一个版本来支持向后兼容。
  2. 我们需要为每个 Activity 覆盖 attachBaseContext 以反射(reflect)更改。

实现如下:

@TargetApi(Build.VERSION_CODES.N)
private static Context updateResources(Context context, String language) {
Locale locale = new Locale(language);
Locale.setDefault(locale);

Configuration configuration = context.getResources().getConfiguration();
configuration.setLocale(locale);
configuration.setLayoutDirection(locale);

return context.createConfigurationContext(configuration);
}

@SuppressWarnings("deprecation")
private static Context updateResourcesLegacy(Context context, String language) {
Locale locale = new Locale(language);
Locale.setDefault(locale);

Resources resources = context.getResources();

Configuration configuration = resources.getConfiguration();
configuration.locale = locale;
configuration.setLayoutDirection(locale);

resources.updateConfiguration(configuration, resources.getDisplayMetrics());
return context;
}

为了支持向后兼容,在更改语言之前检查版本:

public static Context setLocale(Context context, String language) {
// You can save SharedPreference here

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
return updateResources(context, language);
}

return updateResourcesLegacy(context, language);
}

在您的 LoginActivity 中,更改语言环境后,您不必重新创建 Activity ,您可以获取资源然后手动更改每个 TextView

Context context = LocaleUtils.setLocale(this, lang);
Resources resources = context.getResources();
yourFirstTextView.setText(resources.getString(R.string.your_first_text_res)
// ... yourSecondTextView....

在每个 Activity 中,为了反射(reflect)变化,添加这个函数:

@Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(LocaleUtils.onAttach(newBase));
}

顺便说一句,有一个错误,你不能改变工具栏的标题语言。在您的 onCreate() 中,手动调用此函数,setTitle("your Title")

我知道这些问题很丑陋,解决方案也有点老套。但是让我们试一试。让我知道这是否对您有帮助。 :)

完整的源代码可以在这里找到:https://github.com/gunhansancar/ChangeLanguageExample/blob/master/app/src/main/java/com/gunhansancar/changelanguageexample/helper/LocaleHelper.java

有很棒的文章:https://gunhansancar.com/change-language-programmatically-in-android/

关于Android 在第二次更改区域设置后从默认字符串文件 (strings.xml) 加载值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53985529/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com