Android 如何在更改应用程序内部的语言(区域设置)后刷新活动
我的应用程序用户可以通过应用程序的设置更改语言。是否可以在不影响常规语言设置的情况下更改应用程序内部的语言? 这对我很有用,我已经试过了。更改语言后,新创建的活动显示为更改后的新语言,但当前活动和先前创建的处于暂停状态的活动不会更新。如何更新活动? 我也花了很多时间试图立即应用偏好更改,但没有成功。当应用程序重新启动时,所有活动都会重新创建,所以现在语言已正确更改Android 如何在更改应用程序内部的语言(区域设置)后刷新活动,android,Android,我的应用程序用户可以通过应用程序的设置更改语言。是否可以在不影响常规语言设置的情况下更改应用程序内部的语言? 这对我很有用,我已经试过了。更改语言后,新创建的活动显示为更改后的新语言,但当前活动和先前创建的处于暂停状态的活动不会更新。如何更新活动? 我也花了很多时间试图立即应用偏好更改,但没有成功。当应用程序重新启动时,所有活动都会重新创建,所以现在语言已正确更改 android:configChanges="locale" 还为所有活动添加了清单。并且还支持所有屏幕。 目前我还没有在act
android:configChanges="locale"
还为所有活动添加了清单。并且还支持所有屏幕。
目前我还没有在activity的onResume()方法中执行任何操作。
是否有任何方法可以刷新或更新活动(无需完成并重新启动)?我是否在onResume()方法中遗漏了一些要做的事情 由于已为现有区域设置加载字符串资源,因此已打开的活动不会使用新区域设置中的字符串自动显示。解决此问题的唯一方法是重新加载所有字符串并在视图上再次设置它们。通常,对
setContentView(…)
的调用将能够覆盖这一点(取决于您的活动结构),但它当然会产生失去任何视图状态的副作用
public void onResume() {
super.onResume();
...
if (localeHasChanged) {
setContentView(R.layout.xxx);
}
...
}
您可能不希望每次都在onResume()
中重新加载视图,但仅当区域设置发生更改时才重新加载视图。检查何时更新视图(即localeHasChanged
)是将区域设置更改事件传播到以前的活动。这可以通过多种方式完成,例如使用静态单例状态或将此事件持久化到存储器
您还可以尝试在更改区域设置时尽量减少可以打开的活动数量,例如,通过让选择位于初始屏幕之一。如果我想象您在manifest.xml中设置
android:configChanges
,并为多种语言创建多个目录,例如:值fr或值nl
,我可以建议此代码(在活动类中):
我测试了这个代码,它是正确的
更改语言后,新创建的活动显示为更改后的新语言,但当前活动和先前创建的处于暂停状态的活动不会更新。如何更新活动
在API 11(蜂巢)之前,使现有活动以新语言显示的最简单方法是重新启动它。这样,您就不必自己重新加载每个资源了
private void restartActivity() {
Intent intent = getIntent();
finish();
startActivity(intent);
}
在SharedPreferenceChangeListener上注册一个,如果语言首选项已更改,则在其OnShredReferenceChanged()
中调用restartActivity()
。在我的示例中,只有PreferenceActivity被重新启动,但是您应该能够通过设置标志在ActivityResume上重新启动其他活动
更新(感谢@stackunderflow):从API 11(蜂巢)开始,您应该使用重新创建()
,而不是重新启动()
我有一个关于这个话题的博客,内容更详细,但它是用中文写的。完整的源代码在github上:对于Android 4.2(API 17),您需要在AndroidManifest.xml中使用Android:configChanges=“locale | layoutDirection”
。请参见我用此代码解决了我的问题
public void setLocale(String lang) {
myLocale = new Locale(lang);
Resources res = getResources();
DisplayMetrics dm = res.getDisplayMetrics();
Configuration conf = res.getConfiguration();
conf.locale = myLocale;
res.updateConfiguration(conf, dm);
onConfigurationChanged(conf);
}
@Override
public void onConfigurationChanged(Configuration newConfig)
{
iv.setImageDrawable(getResources().getDrawable(R.drawable.keyboard));
greet.setText(R.string.greet);
textView1.setText(R.string.langselection);
super.onConfigurationChanged(newConfig);
}
我们的做法是使用广播:
每次用户更改语言时发送广播
在AppActivity.onCreate()中注册广播接收器,并在AppActivity.onDestroy()中注销广播接收器
在BroadcastReceiver.onReceive()
中,只需重新启动活动
AppActivity
是所有其他活动子类的父活动
下面是我的代码片段,没有在项目外测试,但应该给你一个好主意
当用户更改语言时
sendBroadcast(new Intent("Language.changed"));
在家长活动中
public class AppActivity extends Activity {
/**
* The receiver that will handle the change of the language.
*/
private BroadcastReceiver mLangaugeChangedReceiver;
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// ...
// Other code here
// ...
// Define receiver
mLangaugeChangedReceiver = new BroadcastReceiver() {
@Override
public void onReceive(final Context context, final Intent intent) {
startActivity(getIntent());
finish();
}
};
// Register receiver
registerReceiver(mLangaugeChangedReceiver, new IntentFilter("Language.changed"));
}
@Override
protected void onDestroy() {
super.onDestroy();
// ...
// Other cleanup code here
// ...
// Unregister receiver
if (mLangaugeChangedReceiver != null) {
try {
unregisterReceiver(mLangaugeChangedReceiver);
mLangaugeChangedReceiver = null;
} catch (final Exception e) {}
}
}
}
这还将刷新更改语言的活动(如果它是上述活动的子类)
这会使您丢失任何数据,但如果这很重要,您应该已经使用Activity.onSaveInstanceState()
和Activity.onRestoreInstanceState()
(或类似工具)处理好了
让我知道你对此的想法
干杯 调用此方法以更改应用程序区域设置:
public void settingLocale(Context context, String language) {
Locale locale;
Configuration config = new Configuration();
if(language.equals(LANGUAGE_ENGLISH)) {
locale = new Locale("en");
Locale.setDefault(locale);
config.locale = locale;
}else if(language.equals(LANGUAGE_ARABIC)){
locale = new Locale("hi");
Locale.setDefault(locale);
config.locale = locale;
}
context.getResources().updateConfiguration(config, null);
// Here again set the text on view to reflect locale change
// and it will pick resource from new locale
tv1.setText(R.string.one); //tv1 is textview in my activity
}
注意:将字符串放在value和values-文件夹中。您可以使用重新创建()
在语言更改时重新启动活动
我正在使用以下代码在语言更改时重新启动活动:
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
Configuration config = getBaseContext().getResources().getConfiguration();
String lang = settings.getString("lang_list", "");
if (! "".equals(lang) && ! config.locale.getLanguage().equals(lang)) {
recreate(); //this is used for recreate activity
Locale locale = new Locale(lang);
Locale.setDefault(locale);
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
}
逐步进近完成进近,可在所有API级设备上运行
使用此方法,它将在不重新创建屏幕上现有活动的情况下工作
使用attachBaseContext的基本活动来设置区域设置语言并将此活动扩展到所有活动
打开类BaseAppCompactActivity():AppCompatActivity(){
}
使用应用程序attachBaseContext和OnConfiguration Changed
设置区域设置语言
公共类MyApplication扩展了应用程序{
/**
* overide to change local sothat language can be chnaged from android device nogaut and above
*/
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(LocaleHelper.INSTANCE.onAttach(base));
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
setLanguageFromNewConfig(newConfig);
super.onConfigurationChanged(newConfig);
}
/*** also handle chnage language if device language chnaged **/
private void setLanguageFromNewConfig(Configuration newConfig){
Prefs.putSaveLocaleLanguage(this, selectedLocaleLanguage );
LocaleHelper.INSTANCE.onAttach(this);
}
使用Locale Helper处理语言更改,此方法适用于所有设备
对象LocaleHelper{
private var defaultLanguage:String=KycUtility.KYC_LANGUAGE.ENGLISH.languageCode
fun onAttach(context: Context, defaultLanguage: String): Context {
return setLocale(context, defaultLanguage)
}
fun setLocale(context: Context, language: String): Context {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
updateResources(context, language)
} else updateResourcesLegacy(context, language)
}
@TargetApi(Build.VERSION_CODES.N)
private fun updateResources(context: Context, language: String): Context {
val locale = Locale(language)
Locale.setDefault(locale)
val configuration = context.getResources().getConfiguration()
configuration.setLocale(locale)
configuration.setLayoutDirection(locale)
return context.createConfigurationContext(configuration)
}
private fun updateResourcesLegacy(context: Context, language: String): Context {
val locale = Locale(language)
Locale.setDefault(locale)
val resources = context.getResources()
val configuration = resources.getConfiguration()
configuration.locale = locale
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
configuration.setLayoutDirection(locale)
}
resources.updateConfiguration(configuration, resources.getDisplayMetrics())
return context
}
}
此解决方案在2.2版本中不起作用,对吗?您使用了哪个版本的sdk?我使用了2.2和4.0。我没有任何问题!如果它是ListActivity呢?@benleung没什么不同,ListActivity扩展了Activity并更改了OnConfigurationmethod@benleung我不知道你的问题是什么如果你想知道abo
override fun attachBaseContext(newBase: Context) {
super.attachBaseContext(LocaleHelper.onAttach(newBase))
}
/**
* overide to change local sothat language can be chnaged from android device nogaut and above
*/
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(LocaleHelper.INSTANCE.onAttach(base));
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
setLanguageFromNewConfig(newConfig);
super.onConfigurationChanged(newConfig);
}
/*** also handle chnage language if device language chnaged **/
private void setLanguageFromNewConfig(Configuration newConfig){
Prefs.putSaveLocaleLanguage(this, selectedLocaleLanguage );
LocaleHelper.INSTANCE.onAttach(this);
}
fun onAttach(context: Context, defaultLanguage: String): Context {
return setLocale(context, defaultLanguage)
}
fun setLocale(context: Context, language: String): Context {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
updateResources(context, language)
} else updateResourcesLegacy(context, language)
}
@TargetApi(Build.VERSION_CODES.N)
private fun updateResources(context: Context, language: String): Context {
val locale = Locale(language)
Locale.setDefault(locale)
val configuration = context.getResources().getConfiguration()
configuration.setLocale(locale)
configuration.setLayoutDirection(locale)
return context.createConfigurationContext(configuration)
}
private fun updateResourcesLegacy(context: Context, language: String): Context {
val locale = Locale(language)
Locale.setDefault(locale)
val resources = context.getResources()
val configuration = resources.getConfiguration()
configuration.locale = locale
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
configuration.setLayoutDirection(locale)
}
resources.updateConfiguration(configuration, resources.getDisplayMetrics())
return context
}