Android通过代码实现多语言切换
前言
最近接手一个Android项目,需要实现对维吾尔族语的支持。虽然做了这么久的android开发,只做过多语言支持,但做应用内部多语言支持还是第一次,而且还是对维吾尔语的支持。所以,又是一次面向搜索引擎编程。
面向搜索编程
如果我们搜索“android 多语言切换”,我相信得到大部分的答案是千篇一律的,连文章都长的一样:
Locale locale = new Locale("zh"); Locale.setDefault(locale); Configuration config = new Configuration(); config.locale = locale; getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
以上代码应该说没什么大问题,毕竟确实可以工作,可以实现需求。但是,作为一个强迫症患者,我实际受不了有2处划线的地方,也就是说上面代码中有2处被废弃了(没错,API 25被废弃的):
config.locale = locale; getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
看到有2处被废弃了,必须进去看看啊。
/** * Current user preference for the locale, corresponding to * <a href="{@docRoot}guide/topics/resources/providing-resources.html#LocaleQualifier">locale</a> * resource qualifier. * * @deprecated Do not set or read this directly. Use {@link #getLocales()} and * {@link #setLocales(LocaleList)}. If only the primary locale is needed, * <code>getLocales().get(0)</code> is now the preferred accessor. */ @Deprecated public Locale locale;
很显然我们找到了替代方法:
config.setLocales(LocaleList); config.setLocale(locale);
很好,没问题。继续查看下一个:
/** * Store the newly updated configuration. * * @deprecated See {@link android.content.Context#createConfigurationContext(Configuration)}. */ @Deprecated public void updateConfiguration(Configuration config, DisplayMetrics metrics) { updateConfiguration(config, metrics, null); }
很简单嘛,代替方法也找到了哦。于是就这么写了下去:
Locale locale = new Locale("ug"); final Resources res = getResources(); final Configuration config = res.getConfiguration(); config.setLocale(locale); // getLocale() should return a Locale createConfigurationContext(config);
完全不好用!怎么写就是不好用。再仔细一看,文档上说createConfigurationContext(config)
会返回一个新的Context,然而对新Context如何处理只字未提。又是一番面向搜索编程,终于找到了正确姿势:
@Override protected void attachBaseContext(Context newBase) { Locale locale = new Locale("ug"); final Resources res = newBase.getResources(); final Configuration config = res.getConfiguration(); config.setLocale(locale); // getLocale() should return a Locale final Context newContext = newBase.createConfigurationContext(config); super.attachBaseContext(newContext); }
我们的Activity应该重写这个方法。然后当Activity被创建的时候,新的Context将被应用。需要注意的,如果你想让当前Activity生效,你需要调用recreate()
。
当然啦,我们也可以写个工具类:
public class ConfigurationWrapper { private ConfigurationWrapper() { } public static Context wrapConfiguration(@NonNull final Context context, @NonNull final Configuration config) { return context.createConfigurationContext(config); } public static Context wrapLocale(@NonNull final Context context,@NonNull final Locale locale) { final Resources res = context.getResources(); final Configuration config = res.getConfiguration(); config.setLocale(locale); return wrapConfiguration(context, config); } }
然后你就可以这样使用。如果你想更改configuration,就可以用wrapConfiguration
。
@Override protected void attachBaseContext(Context newBase) { super.attachBaseContext(ConfigurationWrapper.wrapLocale(newContext, getLocale())); }
关于Locale
实现多语言切换用到了Locale。Locale里很多常见国家和地区以及语言,如果我们做常见的语言,可以直接调用系统的,比如Locale.CHINESE
。但是这次做的维吾尔语的适配,略我坑一下。
首先,维吾尔语的英文名字叫Uyghur。Locale里并没有,也可能是我找的不对。
其次,Uyghur是阿拉伯系的。嗯,没错,有个词叫RTL,会出现神奇的东西。
最后,AndroidStudio的values里面是有Uyghur选项的。并且有相对应选项,其中就包括中国,我猜这就是维吾尔语。所以就建了一个,全名是:values-ug-rCN
。
问题是,我最开始直接这样写的:
Locale locale = new Locale("ug-rCN");
好吧,是我太天真,不好用。机智的我看了看Locale的构造方法。后来猜了一个结论
ug代表语种,rCN代表国家和地区。比如说同样都是中文zh,但分了很多国家和地区,如中国,台湾,香港以及新家坡等
所以下面的写法才是正确姿势:
Locale locale = new Locale("ug", Locale.CHINA.getCountry());
结束

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Android Studio DeBug
Android Studio DeBug 额,之前都是用log日志输出,自己想要的东西.搞得代码到处都是Log.i()... 突然有一天,,,自己get到了,Android 断点....调试...., 世界就变得不一样了.... 这篇文章,算是自己阅读和实战后的笔记吧~ 1.adb连接后,打开debug 这里写图片描述 2.debug断点的设置 这里写图片描述 3.debug的面板分析 在你,点击第一步的ok之后, 会弹出debug的窗口.其中的界面如下. 区域分别为 单步调试区 断点管理区 求值表达式 线程帧栈区 对象变量区 变量观察区 这里写图片描述 4.debug,演示操作 这里写图片描述 5.debug操作姿势--单步调试区 该区提供了调试的主要操作,和你所熟知的一样的,主要有:Step over、step into、force step into、step out、drop frame。 5.1 全局数值监视 watch 这里写图片描述 5.2 变量变化 variables 这里写图片描述 5.3 交互式解释器Evaluate expression 你可以执行任何你想要执行的...
- 下一篇
关于线程,还有这些是你需要知道的!
image 有什么料? 进一步理解多线程场景下会出现的问题; 学会正确处理并发操作中的通讯和同步。 现在,多了解些线程吧 在日常开发中,线程常常被用作为提升程序效率的重要手段。在CoorChice的这篇文章中,CoorChice介绍了线程的基本运作。链接: 【你知道Thread线程是如何运作的吗?:http://www.jianshu.com/p/8862bd2b6a29】 本篇,CoorChice将从多线程的角度来进一步介绍线程的相关知识。首先,我们需要了解一些基本知识。 主内存和工作内存 主内存: 暂且可以理解为内存模型中堆内存。它储存了进程的所有共享变量。我们知道,一个进程中可能存在包括主线程在内的多条线程。++主内存中的共享变量是对所有线程可见的。++ 工作内存: 为了提高效率,每个线程都配有一个私有的工作内存。主内存中的共享变量需要拷贝到线程的私有内存中,之后线程对该变量的操作就是在自己的工作内存中进行的。++当值发生改变时,在线程退出之前,会被更新到主内存中。++ 想了解更多和Java内存相关的知识,可以看看CoorChice的这几篇文章: 【Android内存基础——Ja...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- 设置Eclipse缩进为4个空格,增强代码规范
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- SpringBoot2整合Redis,开启缓存,提高访问速度
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- SpringBoot2全家桶,快速入门学习开发网站教程