我正在使用一个Android应用程序,在该应用程序中,我只需一个按钮即可在主屏幕上更改语言环境(英语为阿拉伯语)。它在主屏幕上可以正常工作,但是当我多次更改语言时会出现问题。 请按照以下步骤进行重新生成:
English
,我将其更改为Arabic
。 (效果很好)Arabic
)English
更改为Arabic
。 (在登录屏幕上工作)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);
}
}
}
这是登录活动的代码
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应用程序,所以如果有错误请原谅。预先感谢。
答案 0 :(得分:1)
来自Android文档:
默认情况下,Android使用设备的语言环境来选择适当的语言相关资源。而且在大多数情况下,此行为对于常见应用程序来说就足够了。
内部更改语言是一个例外。
首先,请阅读this documentation并确认设计的缺陷。
总而言之,这里有两件事我要提及:
updateConfiguration
已过时,因此我们需要另一个版本来支持向后兼容。attachBaseContext
以反映更改。这是实现:
@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
中,更改语言环境后,无需重新创建活动,您可以获取资源,然后手动更改每个TextView
。
Context context = LocaleUtils.setLocale(this, lang);
Resources resources = context.getResources();
yourFirstTextView.setText(resources.getString(R.string.your_first_text_res)
// ... yourSecondTextView....
在每个活动中,为了反映变化,请添加此功能:
@Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(LocaleUtils.onAttach(newBase));
}
顺便说一句,有一个错误,您不能更改标题Toolbar
的语言。在您的onCreate()
中,手动调用此功能,setTitle("your Title")
我知道这些问题很丑陋,解决方案有些棘手。但是,请尝试一下。让我知道这是否对您有帮助。 :)
精彩文章:https://gunhansancar.com/change-language-programmatically-in-android/
答案 1 :(得分:0)
首先,您需要确保在用户更改本地用户后,关闭所有活动并重新启动应用程序,诸如此类
Intent intent = new Intent(AcSettingsView.this, MainActivityView.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finishAffinity();
要注意的另一件事是确保每次应用启动时都设置本地用户 在您的第一个屏幕中
helper = new PreferenceHelper(this);
String lang = helper.getData(Constants.LANGUAGE_CODE);
if (eng) {
Utility.setLocale(getBaseContext(), Constants.ENGLISH_CODE);
} else {
Utility.setLocale(getBaseContext(), Constants.ARABIC_CODE);
}