是否有可能在使用Android资源的同时以编程方式改变应用程序的语言?
如果不是,是否可以用特定的语言请求资源?
我想让用户改变应用程序的语言从应用程序。
是否有可能在使用Android资源的同时以编程方式改变应用程序的语言?
如果不是,是否可以用特定的语言请求资源?
我想让用户改变应用程序的语言从应用程序。
当前回答
如果你正在使用片段,并且你想在Android中以编程方式更改应用程序语言,请使用此方法
public void setLocale(Activity activity, String languageCode) {
Locale locale = new Locale(languageCode);
Locale.setDefault(locale);
Resources resources = activity.getResources();
Configuration config = resources.getConfiguration();
config.setLocale(locale);
resources.updateConfiguration(config, resources.getDisplayMetrics());
SettingsFragment settingsFragment = new SettingsFragment();
FragmentManager fragmentManager = requireActivity().getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
activity.overridePendingTransition(0,0);
fragmentTransaction.replace(R.id.main, settingsFragment).commit();
}
这样叫它
setLocale(requireActivity(),"fr");
只需要用你的片段名改变SettingsFragment,在你调用方法的地方,这基本上是刷新布局来获得视图上的新字符串 如果你想在另一个类上设置这个方法只需像这样添加context
public void setLocale(Activity activity, String languageCode,Context context) {
Locale locale = new Locale(languageCode);
Locale.setDefault(locale);
Resources resources = activity.getResources();
Configuration config = resources.getConfiguration();
config.setLocale(locale);
resources.updateConfiguration(config, resources.getDisplayMetrics());
SettingsFragment settingsFragment = new SettingsFragment();
FragmentManager fragmentManager = ((AppCompatActivity) context).getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
activity.overridePendingTransition(0,0);
fragmentTransaction.replace(R.id.main, settingsFragment).commit();
}
其他回答
Mayuri的答案是正确的,但这只适用于Api 33或更高的版本。以下是逐步向后兼容的解决方案:
步骤1:在res/xml文件夹下创建locales_config.xml。
//res/xml/locales_config.xml
<?xml version="1.0" encoding="utf-8"?>
<locale-config xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Add your required languages -->
<locale android:name="hi" />
<locale android:name="en" />
</locale-config>
步骤2:在Application的Manifest中添加localeConfig
<manifest>
<application
android:localeConfig="@xml/locales_config">
</application>
步骤3:在Manifest中应用此服务
<service
android:name="androidx.appcompat.app.AppLocalesMetadataHolderService"
android:enabled="false"
android:exported="false">
<meta-data
android:name="autoStoreLocales"
android:value="true" />
</service>
步骤4:在应用程序的模块级构建中使用resConfigs属性指定相同的语言。gradle文件:
android {
defaultConfig {
...
resConfigs "hi","en"
}
}
(要求appCompat版本1.6.0或更高)
implementation 'androidx.appcompat:appcompat:1.6.0'
第5步:现在你可以使用下面的代码来更改应用程序语言(在android 9,10,12和13上测试)
LocaleListCompat appLocale = LocaleListCompat.forLanguageTags("hi"); //Give user selected language code
AppCompatDelegate.setApplicationLocales(appLocale);
这里列出的解决方案没有一个对我有用。
如果AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES),语言没有在android >= 7.0上切换
这个LocaleUtils工作得很好: https://gist.github.com/GigigoGreenLabs/7d555c762ba2d3a810fe
LocaleUtils
public class LocaleUtils {
public static final String LAN_SPANISH = "es";
public static final String LAN_PORTUGUESE = "pt";
public static final String LAN_ENGLISH = "en";
private static Locale sLocale;
public static void setLocale(Locale locale) {
sLocale = locale;
if(sLocale != null) {
Locale.setDefault(sLocale);
}
}
public static void updateConfig(ContextThemeWrapper wrapper) {
if(sLocale != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
Configuration configuration = new Configuration();
configuration.setLocale(sLocale);
wrapper.applyOverrideConfiguration(configuration);
}
}
public static void updateConfig(Application app, Configuration configuration) {
if(sLocale != null && Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
//Wrapping the configuration to avoid Activity endless loop
Configuration config = new Configuration(configuration);
config.locale = sLocale;
Resources res = app.getBaseContext().getResources();
res.updateConfiguration(config, res.getDisplayMetrics());
}
}
}
将此代码添加到应用程序
public class App extends Application {
public void onCreate(){
super.onCreate();
LocaleUtils.setLocale(new Locale("iw"));
LocaleUtils.updateConfig(this, getBaseContext().getResources().getConfiguration());
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
LocaleUtils.updateConfig(this, newConfig);
}
}
活动中的代码
public class BaseActivity extends AppCompatActivity {
public BaseActivity() {
LocaleUtils.updateConfig(this);
}
}
如果你想在你的应用中保持语言变化,你必须做两件事。
首先,创建一个base Activity,让你所有的Activity都从下面扩展:
public class BaseActivity extends AppCompatActivity {
private Locale mCurrentLocale;
@Override
protected void onStart() {
super.onStart();
mCurrentLocale = getResources().getConfiguration().locale;
}
@Override
protected void onRestart() {
super.onRestart();
Locale locale = getLocale(this);
if (!locale.equals(mCurrentLocale)) {
mCurrentLocale = locale;
recreate();
}
}
public static Locale getLocale(Context context){
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
String lang = sharedPreferences.getString("language", "en");
switch (lang) {
case "English":
lang = "en";
break;
case "Spanish":
lang = "es";
break;
}
return new Locale(lang);
}
}
注意,我将新语言保存在sharedPreference中。
其次,像这样创建一个应用程序的扩展:
public class App extends Application {
@Override
public void onCreate() {
super.onCreate();
setLocale();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
setLocale();
}
private void setLocale() {
final Resources resources = getResources();
final Configuration configuration = resources.getConfiguration();
final Locale locale = getLocale(this);
if (!configuration.locale.equals(locale)) {
configuration.setLocale(locale);
resources.updateConfiguration(configuration, null);
}
}
}
注意,getLocale()与上面相同。
这是所有! 我希望这能帮助到一些人。
阿拉伯语/RTL支持
您必须通过- attachBaseContext()更新您的语言设置。 对于android版本N及以上,您必须使用createconfigationcontext () & updateConfiguration() -否则RTL布局无法正常工作
@Override protected void attachBaseContext(Context newBase) { super.attachBaseContext(updateBaseContextLocale(newBase)); } public Context updateBaseContextLocale(Context context) { String language = SharedPreference.getInstance().getValue(context, "lan");//it return "en", "ar" like this if (language == null || language.isEmpty()) { //when first time enter into app (get the device language and set it language = Locale.getDefault().getLanguage(); if (language.equals("ar")) { SharedPreference.getInstance().save(mContext, "lan", "ar"); } } Locale locale = new Locale(language); Locale.setDefault(locale); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { updateResourcesLocale(context, locale); return updateResourcesLocaleLegacy(context, locale); } return updateResourcesLocaleLegacy(context, locale); } @TargetApi(Build.VERSION_CODES.N) private Context updateResourcesLocale(Context context, Locale locale) { Configuration configuration = context.getResources().getConfiguration(); configuration.setLocale(locale); return context.createConfigurationContext(configuration); } @SuppressWarnings("deprecation") private Context updateResourcesLocaleLegacy(Context context, Locale locale) { Resources resources = context.getResources(); Configuration configuration = resources.getConfiguration(); configuration.locale = locale; resources.updateConfiguration(configuration, resources.getDisplayMetrics()); return context; }
androidx。Appcompat: Appcompat用户,以上解决方案将在1.3.0版本后工作。 就像这里提到的。