最近工作中突然要求要项目进行国际化,之前没遇到过。但是也很简单呀,只需要把添加一个相应语言的的strings.xml的资源文件就好了,不是吗?这样只要切换系统语言就能切换app的文字语言了。
但是由此引发了一个稍微深入一点的问题,那就是如果要实现在app中不跟随系统切换语言,可以直接切换语言哪又要怎么做呢?这种功能是支付宝/微信都有的,功能如下图:
多语言切换.gif
于是努力的研究了一下子,发现实现这个功能也不难,主要涉及到Configuration和Locale这两个类,其中Configuration是设置app配置的,Locale则是表示地理信息等东西,更多详细内容需要大家自己去了解。
基本的大家已经了解了,那么要如何实现它呢?
首先我们要能切换不同的语言,那么必然需要不同的资源包,所以第一步是建立中文和英文两个不同的strings.xml。
然后就使用Configuration和Locale配置语言了,关键代码如下:
/**
* 切换语言
*
* @param language
*/
private void switchLanguage(String language) {
//设置应用语言类型
Resources resources = getResources();
Configuration config = resources.getConfiguration();
DisplayMetrics dm = resources.getDisplayMetrics();
if (language.equals("zh_simple")) {
config.locale = Locale.SIMPLIFIED_CHINESE;
} else if (language.equals("en")) {
config.locale = Locale.ENGLISH;
} else {
config.locale = Locale.getDefault();
}
resources.updateConfiguration(config, dm);
//更新语言后,destroy当前页面,重新绘制
finish();
Intent it = new Intent(MainActivity.this, MainActivity.class);
//清空任务栈确保当前打开activit为前台任务栈栈顶
it.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(it);
}
通过使用这个方法,传入zh_simple或者en两个string类型,就能选择想要的语言了。
值得注意的是假如你的 App 存在某个 activity 和当前设置页 activity 不在一个 task 栈内的话(比如你从某个通知页用 FLAG_ACTIVITY_NEW_TASK 启动的一个 activity),就不会应用语言设置。因此可以直接杀掉当前 App 的进程,保证是“整个”重启了。所以最好就是清除所有任务栈和进程。
重启app之后使用之前设置好的语言
这个问题挺傻的,但是有时候就是拐不过弯来。
事实上我们只需要在设置语言的时候,把当前设置好的语言保存在sharedpreference中就可以了。然后设置一个application的类,在其中的时候读取配置信息就可以了。
图片国际化与尺寸国际化
既然语言可以国际化,那么图片或者尺寸dimens可不可以国际化呢?
其实这也是可以得,只要在相应的目录下建立不同语言的资源包便可以实现,效果如下:
GIF.gif
方法如下:
图片国际化.PNG
尺寸国际化.PNG
在这里,我设置了两种图片,中国地图和美国地图,将美国地图房子drawable-en-hdpi的目录中,然后选择语言就会出现不同的图片。
然后再values-en目录中建立了新的dimens.xml文件,如下:
100dp
100dp
而在values目录的dimens.xml则设置为300dp,这时两种语言切换后,显示的大小就不同了。
其他资源国际化
在往外延伸一点,既然图片和尺寸都能国际化,那么res资源文件夹下的其他东西是不是也可以国际化呢?答案是可以的。
尝试在res文件夹下创建raw文件夹,放置了音频,然后又创建了raw-en的目录,放置另一个音频,切换语言后,两者也是不同的。
因此可以判断,只要是res资源文件夹下的资源,都是可以进行国际化操作的。