时间:2021-01-16 12:29:04 | 栏目:Android代码 | 点击:次
最近项目上产品经理提了个需求,要求关闭语言国际化,不管手机系统设置那个国家的语言,都要显示汉语,好吧,既然有需求,那就做吧。但是项目中已经有英文的配置了,且是作为默认String提供的,这么多翻译好的文字,直接删除掉替换成中文为默认String又感觉弃之可惜。故网上Google下解决方案。就开始往下看吧。
一、代码中动态设置应用显示语言(手动控制使用values-zh-rCN下字符串)
这个方法是通过改变Resource中的配置来实现的,代码如下:
public static void initAppLanguage(Context context) { if (context == null) { return; } Locale.setDefault(Locale.CHINA); Configuration config = context.getResources().getConfiguration(); config.locale = Locale.CHINA; context.getResources().updateConfiguration(config , context.getResources().getDisplayMetrics()); }
上面方法我们可以在MyApplication中设置也可以在Activity的基类中调用
但是上面的方法还是不足以让我们的应用一直显示指定的某种语言文字的。因为我们的应用在运行阶段中,系统语言发生了改变后,我们的应用还是会被切换语言的,如果没有指定语言,就显示默认的语言。这肯定不是我们要看到的结果,那就到了标题中提到的语言切换监听了。
二、语言切换监听
1.广播方式监听
我们可以通过监听系统广播来实现(广播静态注册动态注册都可以,动态注册把握好注册时机)
/** * ClassName: LocaleChangeReceiver * Description:(这里用一句话描述这个类的作用) * Created by chensf on 2016-8-17 16:47. */ public class LocaleChangeReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Log.v(TAG, "mReceiver onReceive intent.getAction(): "+intent.getAction()); if(intent.getAction().equals(Intent.ACTION_LOCALE_CHANGED)) { Log.e("LocaleChangeReceiver","Language change"); SystemUtil.initAppLanguage(context); } } }
这里我们通过监听Intent.ACTION_LOCALE_CHANGED广播,在系统语言切换后我们会得到通知,然后就爱干嘛干嘛了,这里我通过调用上面 提到的设置语言方法,将语言设置为初始设定语言。网上大多都是采用这种方式来监听语言切换,其实还有另外一种方式。
2.重写onConfigurationChanged方法
一些系统设置变化后都会回调这个方法,所以我们可以从这里下手。
那在哪里重写这个方法呢,这个方法大家是不是感觉很熟悉,监听横竖屏切换是不是有用到过呢,提到横竖屏切换,这里顺便讲点题外话
在横竖屏切换的时候,我们为了避免Activity重新调用onCreate,一般都会重写这个方法,但是,横竖屏切换后Activity没有调用onConfigurationChanged而是依旧调用了onCreate,因为我们Activity默认是不回调onConfigurationChanged的,开启方法就是
<activity android:name=".MainActivity" android:configChanges="orientation|screenSize"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
在AndroidManifest中Activity标签下添加android:configChanges="orientation|screenSize,orientation是横竖屏切换的配置,至于为什么要同时加上screenSize,是因为Android3.0之后,如果只设置orientation没有设置screenSize,onConfigurationChanged依旧不会被回调。
那回归正题,大家通过上面的例子知道了这个onConfigurationChanged要在Activity中重写,配置跟上面一致,参数改变了而已
<activity android:name=".MainActivity" android:configChanges="locale|layoutDirection"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
android:configChanges="locale|layoutDirection 这里同样存在一个问题,4.2之前的系统只需要设置locale,4.2+就得多设置layoutDirection这个配置,不然onConfigurationChanged依旧不会被回调。
上面的在Activity重写onConfigurationChanged方式明显存在一个缺点,如果只需要改变某个Activity的语言设置,上面的方式可以适用,如果要改变整个应用的语言设置,上面的方式就很low,要每个Activity都重写onConfigurationChanged,虽然可以在Activity基类中重写,但是,AndroidManifest中还是得每个Activity标签下都去设置
android:configChanges="locale|layoutDirection,说了这么多就不绕弯子了,我们可以在Application中重写onConfigurationChanged
@Override public void onConfigurationChanged(Configuration newConfig) { Log.e("MyApplication","onConfigurationChanged"); super.onConfigurationChanged(newConfig); SystemUtil.initAppLanguage(getBaseContext()); }
这个配置是整个应用设置的,在这里设置语言,能够改变整个应用的语言设置,而且这种方式,无需在AndroidManifest中增加配置,我测试过,在Application中重写onConfigurationChanged,Activity的onConfigurationChanged
依旧能够回调到,但是其中有没有造成什么影响,我这里暂时没有发现。如果有采用我提供的这种方式实现语言切换监听的,遇到问题可以告诉我,我们一起探讨下。