简述
当APP需要给提供多种语音供用户使用的时候,作为开发者的我们自然要涉及到多语言切换的开发,希望我提供的方式能给需要的小伙伴们一点思路,老规矩先上图。
效果如下,可能看起来会比较卡(不知道为啥黑屏时间卡了好久,实际效果是一闪而过)
实现方式
这是最常运用的最普遍的方式,通过创建不同的value 语言文件夹下的的string.xml ,当更改时,切换使用对应的字符资源。
让我们先来创建对应的字符资源文件夹。在main目录下的res文件夹右键新建一个资源文件夹
选中Locale,导入限定资源里
此时会出现各种语言资源,在此项目中,我将新增中文(zh)与英文(en)字符资源 (懒得找的小伙伴其实只要知道对应的语言文化代码,直接自己创建命名也可)
建完之后的目录:
接着再导入本次要使用的EventBus,用于广播通知(也可用Broadcast,这次主要是对于语言切换的实现,故不展开讲)
implementation 'org.greenrobot:eventbus:3.0.0'
然后我们先来实现一个抽象基类:BaseActivity,让其它Activity继承其特性,写一些共有方法,便于我们维护何使用,这里是为了实现多语言切换时,不用在每个Activity中实现切换语言通知时,界面重建与减少繁琐的编写EventBus 的订阅与注销
public abstract class BaseActivity extends AppCompatActivity {
public final static String SWITCH_LANGUAGE = "Language";
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setLanguage();
EventBus.getDefault().register(this);
setContentView(getViewResId());
init();
}
protected void init() {
}
protected abstract int getViewResId();
@Override
protected void onDestroy() {
EventBus.getDefault().unregister(this);
super.onDestroy();
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEvent(String msg) {
switch (msg){
case SWITCH_LANGUAGE:
setLanguage();
recreate();//刷新界面
break;
}
}
private void setLanguage() {
Locale myLocale = new Locale(SPUtils.getLanguage(this));
Resources res = getResources();
DisplayMetrics dm = res.getDisplayMetrics();
Configuration conf = res.getConfiguration();
conf.locale = myLocale;
res.updateConfiguration(conf, dm);
}
}
setLanguage()方法中设置了我们的地理语言环境,将我们设置Locale赋值给Configuration,设置为我们需要的语言环境,再调用 recreate()方法销毁界面再重新创建,此方法只有在API>26以上版本才存在。调用后新创建的活动的生命周期:onCreate->onStart->onResume
其中SPUtils 工具类是用来在关闭应用后,重新打开我们的APP时,记录用户设置的切换语言类型(它本质就是一个小型数据库,随着应用卸载而被销毁)
public class SPUtils {
public static void setLanguage(Context context, String language) {
SharedPreferences.Editor editor = context.getSharedPreferences("Language", context.MODE_PRIVATE).edit();
editor.putString("language", language);
editor.commit();
}
public static String getLanguage(Context context) {
SharedPreferences editor = context.getSharedPreferences("Language", context.MODE_PRIVATE);
return editor.getString("language","zh");//默认中文
}
}
回到我们的主界面来,在XML上直接使用我们在strings中定义的内容,复制strings到对values-en 与 values-zh,自行修改中文与英文的的内容
在XML上的使用是通过@string/name 方式设置
在代码中则是通过调用Resources 的getString 方法获取对应资源文件的id来设置
getResources().getString(R.string.to_one)
现在我们通过跳转ActivityOne(记得要继承我们编写的基类)界面,点击按钮切换语言,XML布局就不给出了
public class ActivityOne extends BaseActivity {
@Override
protected void init() {
onClickEvent();
}
@Override
protected int getViewResId() {
return R.layout.activity_one;
}
private void onClickEvent() {
findViewById(R.id.tv_chinese).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
SPUtils.setLanguage(ActivityOne.this, "zh");
EventBus.getDefault().post(BaseActivity.SWITCH_LANGUAGE);
}
});
findViewById(R.id.tv_english).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
SPUtils.setLanguage(ActivityOne.this, "en");
EventBus.getDefault().post(BaseActivity.SWITCH_LANGUAGE);
}
});
}
}
至此,就实现了语言切换的功能,录制图已贴在最顶部,当然切换方法还有其它方式,这里给出较为常用的一种,希望能给需要的小伙伴们一点启发。