1.场景
我们都知道,在安卓做国际化的过程中,创建不同的value文件夹,引用不同value文件夹下的string就可以实现国际化,系统会根据手机的语言环境自动匹配语言环境,但有时候我们的应用动态设置语言的功能,这时,我们就要来动态更新我们应用的语言.
2.应用
一般像系统设置的一些配置信息,我们都可以使用Configuration
来实现,此时我们会想到我们常用的onConfigurationChanged
,我们常用的屏幕横竖屏切换系统会回调这个方法,此时需要在清单文件配置权限
<uses-permission android:name="android.permission.CHANGE_CONFIGURATION"></uses-permission>
还必须在清单文件中为Activity配置configChanges
信息,否则系统不会回调onConfigurationChanged方法,而是重新走生命周期
<activity
android:name="module.MyActivity"
android:configChanges="orientation"
android:screenOrientation="portrait" />
这时我们会发现,我们经常配置configChanges
的不仅仅只有orientation啊 还有像keyboardHidden等等,确实是这样的,其实不仅仅横竖屏切换时系统会回调
onConfigurationChanged
,还有像一些软键盘的隐藏和显示,系统语言环境的改变,系统字体大小的改变都会回调这个方法,接下来我们来看看configChanges的一些具体的属性.
3.configChanges的属性
这里感谢Android之屏幕方向改变以及onConfigurationChanged事件
Value | Description |
---|---|
mcc | 移动国家号码,由三位数字组成,每个国家都有自己独立的MCC,可以识别手机用户所属国家。 |
mnc | 移动网号,在一个国家或者地区中,用于区分手机用户的服务商。 |
locale | 用户所在地区发生变化。 |
touchscreen | 屏幕发生变化,正常情况下一般不会发生 |
keyboard | 键盘模式发生变化,例如:用户接入外部键盘输入。 |
keyboardHidden | 系统键盘的显示和隐藏 |
navigation | 导航栏类型发生改变,正常情况下一般不会发生 |
orientation | 设备旋转,横向显示和竖向显示模式切换。 |
fontScale | 系统字体缩放发生改变 |
这里我们可以看到locale是表示地区发生改变的 ,其实这些属性都封装在Configuration
里面 ,下面我们看一下怎么动态改变语言环境
4.动态更改语言环境
1.首先在我们选择语言的地方,本地保存设置的语言信息,并动态设置语言环境
private void ChooseLan() {
AlertDialog dialog = new AlertDialog.Builder(this)
.setTitle("请选择语言")
.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, new String[]{"中文,English"}), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//获取系统配置的Locale信息
Locale locale = getResources().getConfiguration().locale;
switch (which) {
case 0:
//在设置语言界面保存设置的语言环境,在用户重新进入应用时使应用处于设置后的
SpUtils.putParam(MyActivity.this, "language", "chinese");
//Locale赋值为当前设置的语言环境
locale = Locale.SIMPLIFIED_CHINESE;
break;
case 1:
SpUtils.putParam(MyActivity.this, "language", "english");
locale = Locale.ENGLISH;
break;
}
//设置语言环境
setLan(locale);
dialog.dismiss();
}
}).show();
}
private void setLan(Locale locale) {
// 获得res资源对象
Resources resources = getResources();
// 获得配置信息对象
Configuration config = resources.getConfiguration();
// 获得屏幕参数:主要是分辨率,像素等。
DisplayMetrics dm = resources.getDisplayMetrics();
// 语言
config.locale = locale;
resources.updateConfiguration(config, dm);
// 刷新activity才能马上奏效
startActivity(new Intent().setClass(this,
MyActivity.class));
finish();
}
2.在进入时,在我们的Application中首先判断用户有没有设置过语言环境,如果设置过就动态设置
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
setLan();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
setLan();
}
/**设置语言信息*/
private void setLan() {
Locale locale ;
String language = SpUtils.getStringParam(this, "language", "");
if (TextUtils.isEmpty(language)){
//用户没有设置,赋值为系统语言环境
locale=getResources().getConfiguration().locale;
}else {
//用户设置过
switch (language){
case "chinese":
locale=Locale.SIMPLIFIED_CHINESE;
break;
case "english":
locale=Locale.ENGLISH;
break;
default:
locale=getResources().getConfiguration().locale;
break;
}
}
// 获得res资源对象
Resources resources = getResources();
// 获得配置信息对象
Configuration config = resources.getConfiguration();
// 获得屏幕参数:主要是分辨率,像素等。
DisplayMetrics dm = resources.getDisplayMetrics();
// 语言
config.locale = locale;
//更新配置信息
resources.updateConfiguration(config, dm);
}
}
Note:以上只演示了中英文的切换,支持安卓兼容的所有语言的切换,同时在value中有多语言的string资源才能生效.
5.扩展
由以上我们可以想到,其实Configuration 所有属性都可以这样动态设置,下面我们来试一下动态改变屏幕的横竖屏切换,不多说了,和设置语言是一样的,直接上代码
//横竖屏切换
int orientation;
private void setOrientation() {
orientation = getResources().getConfiguration().orientation;
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
switch (orientation){
case Configuration.ORIENTATION_LANDSCAPE://横屏
orientation = Configuration.ORIENTATION_PORTRAIT;
break;
case Configuration.ORIENTATION_PORTRAIT:
orientation=Configuration.ORIENTATION_LANDSCAPE;
break;
}
Resources resources = getResources();
Configuration config = getResources().getConfiguration();
config.orientation=orientation;
DisplayMetrics displayMetrics = resources.getDisplayMetrics();
resources.updateConfiguration(config,displayMetrics);
}
});
}