Android多语言适配的示例代码(兼容7.0+)

Android多语言适配的示例代码(兼容7.0+),第1张

概述一、前言1、安卓系统本身对多语言适配就提供了一套框架和API。我们就直接用就可以了。

一、前言

1、安卓系统本身对多语言适配就提供了一套框架和API。我们就直接用就可以了。

2、更换语言必须recreate Activity。目前,没见过可以不重建的方法。常用App,也都是重建的,可以看的到。

3、兼容性问题。现在越来越多设备都是安卓7.0+新手机的安卓版本会更高(安卓8.0+),所以适配是必要的。

4、目前,网上大部分相关文章都是不兼容7.0+的,具体做法一搜一大把。

二、具体做法

1、多语言文件

文件夹命名参考下面博客(网上有很多):

多国语言value文件夹命名

value默认放英文的资源文件,简体中文文件夹命名为values-zh-rCN,不需要翻译的设置translatable如下:

复制代码 代码如下:
<string name="app_name_english" translatable="false">You App English name</string>

2、多语言工具类

public class LanguageUtils { public static final String CHInesE_SIMPLE = "zh_CN"; public static final String ENGliSH = "en"; public static final String auto = "auto"; private static final String TAG = "LanguageUtils"; //public static final String[] LOCALES = Utils.getContext().getResources().getStringArray(R.array.locales); private LanguageUtils() {  throw new UnsupportedOperationException("u can't instantiate me..."); } public static voID setSystemDefaultLocale(Locale locale) { } public static boolean isSetValue(Context context) {  Locale currentLocale = context.getResources().getConfiguration().locale;  return currentLocale.equals(getSetLocale()); } private static Locale getSetLocale() {  String locale = SPUtils.getInstance(BaseConstants.SP.name_APP_SETTINGS).getString(BaseConstants.SP.KEY_LANGUAGE,LanguageUtils.auto);  if (locale.equals(LanguageUtils.auto)) {   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {    return Resources.getSystem().getConfiguration().getLocales().get(0);//解决了获取系统默认错误的问题   } else {    return Locale.getDefault();   }  }  String[] array = locale.split("_");  String language = array[0];  if (array.length > 1) {   String country = array[1];   return new Locale(language,country);  }  return new Locale(language); } public static int getSetIndex() {  String languageSet = SPUtils.getInstance(BaseConstants.SP.name_APP_SETTINGS).getString(BaseConstants.SP.KEY_LANGUAGE,LanguageUtils.auto);  int localeIndex = 0;  switch (languageSet) {   case LanguageUtils.auto:    localeIndex = 0;    break;   case LanguageUtils.CHInesE_SIMPLE:    localeIndex = 1;    break;   case LanguageUtils.ENGliSH:    localeIndex = 2;    break;  }  return localeIndex; } public static Context wrapContext(Context context) {  Resources resources = context.getResources();  Locale locale = LanguageUtils.getSetLocale();  Configuration configuration = resources.getConfiguration();  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {   configuration.setLocale(locale);   LocaleList localeList = new LocaleList(locale);   LocaleList.setDefault(localeList);   configuration.setLocales(localeList);  } else {   configuration.setLocale(locale);  }  return context.createConfigurationContext(configuration); } public static voID applyChange(Context context) {  Resources res = context.getResources();  displayMetrics dm = res.getdisplayMetrics();  Configuration conf = res.getConfiguration();  Locale locale = getSetLocale();  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {   conf.setLocale(locale);   LocaleList localeList = new LocaleList(locale);   LocaleList.setDefault(localeList);   conf.setLocales(localeList);  } else {   conf.setLocale(locale);  }  res.updateConfiguration(conf,dm); }}

3、代码分析&兼容7.0+

3.1、如何获取系统的语言设置,也就是7.0+你选择auto,可以正确切换。

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {    return Resources.getSystem().getConfiguration().getLocales().get(0);//解决了获取系统默认错误的问题   } else {    return Locale.getDefault();   }

看到这篇文章的你,可能已经看过网上很多其他相关的文章,应该知道,7.0+系统有个很奇怪的地方:

如果你在app内切换了语言(比如说是英文),且该语言和系统的设置(比如说是中文)不同,那么你再次切换语言并选择auto时,通过Locale.getDefault()获取会错误,或者你通过LocaleList.get(0)也是错误的,你之前选择的语言(英文)排序被提前了。有些文章的解决方案是在app打开时持久化系统设置,这样你切换app的语言就不会影响你获取系统的设置,但这样没必要,太麻烦(应该是不知道上面的方法)。

7.0+的系统设置也看的出差别,以前,设置系统语言直接选择就可以了,现在你要先添加,然后再排序,排在第一个的才是系统显示的语言!

3.2、写个BaseActivity作为所有Activity父类

新建一个BaseActivity用于继承,重写:

@OverrIDe protected voID attachBaseContext(Context newBase) {  super.attachBaseContext(LanguageUtils.wrapContext(newBase)); }

然后在切换语言后,你要recreate Activity。这个在哪调用就看具体需求了。你可以像微信那样,清空栈,然后直接重启到主界面,也可以在设置界面recreate,但栈内其他Activity,也要想办法通知recreate。

3.3、屏蔽系统设置改变

如果app的语言选项不是auto,那么系统语言设置修改时,app就不应该跟着系统变,而是按照自己设置的语言显示。写一个类继承于Application(注意要在manifest配置哦,不然无效的)

public class MyApp extends Application { private Configuration deltaConfig;@OverrIDe public voID onConfigurationChanged(Configuration newConfig) {  LogUtils.d(TAG,"调用了onConfigurationChanged");  int diff = newConfig.diff(deltaConfig);  String languageSet = SPUtils.getInstance(AppConstants.SP.name_APP_SETTINGS).getString(AppConstants.SP.KEY_LANGUAGE,LanguageUtils.auto);  if (languageSet.equals(LanguageUtils.auto)) {//看app语言设置是不是auto,是的话不管,直接super   super.onConfigurationChanged(newConfig);   deltaConfig = newConfig;  } else if (diff != ActivityInfo.CONfig_LOCALE) {//这个Configuration更改是不是语言,不是的话,也不管   super.onConfigurationChanged(newConfig);   deltaConfig = newConfig;  }   //这里使系统设置语言无效   //相当于省略了   //else{   // return;   //} } @OverrIDe public voID onCreate() {  super.onCreate();  //app打开时记录系统设置  deltaConfig = getApplicationContext().getResources().getConfiguration();  LanguageUtils.applyChange(getApplicationContext());  } }}

3.4、其他问题

Application的Context也要更新

LanguageUtils.applyChange(context);LanguageUtils.applyChange(context.getApplicationContext());

但即使这样,还是有点问题,主要在于:

如果Activity的Title你是在manifest中定义的,如下label:

<activity   androID:name=".ui.activity.AboutActivity"   androID:launchMode="singletop"   androID:label="@string/lable_activity_about"   androID:theme="@style/Apptheme.NoActionbar"/>

那么,即使你更新了ApplicationContext,有些Activity也有可能不生效,而且每次都还不一样,这个没法复现(很迷)。不知道是不是系统BUG(测试系统是一加3 氢OS 8.0),或者是有其他更好的写法?

针对这个问题,只要在activity oncreate() 里setTitle()就好了。这样是不会有什么问题的。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。

您可能感兴趣的文章:Android轻松实现多语言的方法示例Android编程实现动态支持多语言的方法Android应用的多语言支持的实现方法Android实现app应用多语言切换功能Android app应用多语言切换功能实现 总结

以上是内存溢出为你收集整理的Android多语言适配的示例代码(兼容7.0+)全部内容,希望文章能够帮你解决Android多语言适配的示例代码(兼容7.0+)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1142942.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存