簡述
當APP需要給提供多種語音供用戶使用的時候计寇,作為開發(fā)者的我們自然要涉及到多語言切換的開發(fā)颈嚼,希望我提供的方式能給需要的小伙伴們一點思路怜械,老規(guī)矩先上圖。
效果如下弄抬,可能看起來會比較卡(不知道為啥黑屏時間卡了好久茎辐,實際效果是一閃而過)
實現(xiàn)方式
這是最常運用的最普遍的方式,通過創(chuàng)建不同的value 語言文件夾下的的string.xml 掂恕,當更改時拖陆,切換使用對應的字符資源。
讓我們先來創(chuàng)建對應的字符資源文件夾懊亡。在main目錄下的res文件夾右鍵新建一個資源文件夾
選中Locale,導入限定資源里
此時會出現(xiàn)各種語言資源依啰,在此項目中,我將新增中文(zh)與英文(en)字符資源 (懶得找的小伙伴其實只要知道對應的語言文化代碼店枣,直接自己創(chuàng)建命名也可)
建完之后的目錄:
接著再導入本次要使用的EventBus,用于廣播通知(也可用Broadcast速警,這次主要是對于語言切換的實現(xiàn)叹誉,故不展開講)
implementation 'org.greenrobot:eventbus:3.0.0'
然后我們先來實現(xiàn)一個抽象基類:BaseActivity,讓其它Activity繼承其特性闷旧,寫一些共有方法桂对,便于我們維護何使用,這里是為了實現(xiàn)多語言切換時鸠匀,不用在每個Activity中實現(xiàn)切換語言通知時,界面重建與減少繁瑣的編寫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()方法中設置了我們的地理語言環(huán)境逾柿,將我們設置Locale賦值給Configuration缀棍,設置為我們需要的語言環(huán)境,再調用 recreate()方法銷毀界面再重新創(chuàng)建机错,此方法只有在API>26以上版本才存在爬范。調用后新創(chuàng)建的活動的生命周期:onCreate->onStart->onResume
其中SPUtils 工具類是用來在關閉應用后,重新打開我們的APP時弱匪,記錄用戶設置的切換語言類型(它本質就是一個小型數(shù)據庫青瀑,隨著應用卸載而被銷毀)
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)
現(xiàn)在我們通過跳轉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);
}
});
}
}
至此哑诊,就實現(xiàn)了語言切換的功能,錄制圖已貼在最頂部及刻,當然切換方法還有其它方式镀裤,這里給出較為常用的一種,希望能給需要的小伙伴們一點啟發(fā)缴饭。