本文主要是介绍android程序内多语言切换不需要重新启动的解决方案,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
关于android程序内的的多语言切换,一般能搜索到这段代码:
public void switchLanguage(Locale locale) {Configuration config = getResources().getConfiguration();// 获得设置对象Resources resources = getResources();// 获得res资源对象DisplayMetrics dm = resources.getDisplayMetrics();// 获得屏幕参数:主要是分辨率,像素等。config.locale = locale; //语言resources.updateConfiguration(config, dm);}
多数给出的方案是重新启动activity或者重新setContentView,但是微信却能办到不重启又能修改语言,怎么办到的呢?就让鄙人吹吹实现思路吧:首先定义一个多语言切换支持的自定义控件,整个app涉及到多语言的布局的地方都要使用它,控件初始化的时候获取string资源id,保存string资源id,settext的时候要更新string资源id,切换语言的时候用上文所提供的代码,设置完语言后(假设设置成中文),如果重新通过string资源id设置text,那么就会显示中文文字,如果我们不主动去更新,他们就不自觉了,就像泡妹子一样,主动才能到手,所以我们需要对所有的多语言支持的自定义控件进行更新,方法就是通过发送
消息给每一个activity,activity收到后,拿出自己的view,把全部子view列举一次,如果是多语言支持的自定义控件,就更新它,详细步骤看下文:
步骤1:
建立多语言文件夹,并写好多语言所需的文字
values-zh
values-en
…..
不细讲了
步骤2:
定义多语言切换接口,需要自定义view实现它
在控件包(widget包)下建立AppTextView和AppButton
建立接口:LanguageView,包含以下方法:
//由于setText无法被重写,需要添加以下三个必要的方法,如果你的app不需要对多语言的textview修改值(只是xml写死就够了),那就不需要实现他们void setTextById (@StringRes int id);//手动设置textIdvoid setTextWithString (String text);//手动去掉textId,不然重新加载语言的时候会被重置掉void setTextByArrayAndIndex (@ArrayRes int arrId, @StringRes int arrIndex);//手动通过TextArray设置语言void reLoadLanguage();//修改语言时主要调用的方法
步骤3:
自定义多语言切换view:
public class AppTextView extends TextView implements LanguageView {private int textId ;//文字idprivate int hintId ;//hint的idprivate int arrResId,arrResIndex;public AppTextView(Context context) {super(context);init(context, null);}public AppTextView(Context paramContext, AttributeSet paramAttributeSet) {super(paramContext, paramAttributeSet);init(paramContext, paramAttributeSet);}public AppTextView(Context paramContext, AttributeSet paramAttributeSet, int paramInt) {super(paramContext, paramAttributeSet, paramInt);init(paramContext, paramAttributeSet);}/*** 初始化获取xml的资源id* @param context* @param attributeSet*/private void init (Context context,AttributeSet attributeSet) {if (attributeSet!=null) {String textValue = attributeSet.getAttributeValue(ANDROIDXML, "text");if (!(textValue==null || textValue.length()<2)) {//如果是 android:text="@string/testText"//textValue会长这样 @156878785,去掉@号就是资源idtextId = StringUtil.string2int(textValue.substring(1,textValue.length()));}String hintValue = attributeSet.getAttributeValue(ANDROIDXML, "hint");if (!(hintValue==null || hintValue.length()<2)) {hintId = StringUtil.string2int(hintValue.substring(1,hintValue.length()));}}}@Overridepublic void setTextById (@StringRes int strId) {this.textId = strId;setText(strId);}@Overridepublic void setTextWithString(String text) {this.textId = 0;setText(text);}@Overridepublic void setTextByArrayAndIndex (@ArrayRes int arrId, @StringRes int arrIndex) {arrResId = arrId;arrResIndex = arrIndex;String[] strs = getContext().getResources().getStringArray(arrId);setText(strs[arrIndex]);}@Overridepublic void reLoadLanguage () {try {if (textId>0) {setText(textId);} else if (arrResId>0) {String[] strs = getContext().getResources().getStringArray(arrResId);setText(strs[arrResIndex]);}if (hintId>0) {setHint(hintId);}} catch (Exception e) {e.printStackTrace();}}
}
步骤4:
博客出处
编写xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical" android:layout_width="match_parent"android:layout_height="match_parent"><cn.georgeyang.languageupdate.widget.AppTextView
android:text="@string/testText"android:layout_width="wrap_content"android:layout_height="wrap_content" /><cn.georgeyang.languageupdate.widget.AppButton
android:id="@+id/btn"android:text="@string/next"android:layout_width="wrap_content"android:layout_height="wrap_content" /></LinearLayout>
步骤5:
写好activity代码后,添加eventbus,实现activity之间的通信(用其它方式实现通信也行)
gradle添加 compile 'org.greenrobot:eventbus:3.0.0'public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);EventBus.getDefault().register(this);findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {switchLanguage(Locale.CHINESE);ClassEvent event = new ClassEvent();event.msg = "do it";EventBus.getDefault().post(event);}});}public void switchLanguage(Locale locale) {Configuration config = getResources().getConfiguration();// 获得设置对象Resources resources = getResources();// 获得res资源对象DisplayMetrics dm = resources.getDisplayMetrics();// 获得屏幕参数:主要是分辨率,像素等。config.locale = locale; resources.updateConfiguration(config, dm);}@Subscribe(threadMode = ThreadMode.MAIN) //在ui线程执行public void onStringEvent(ClassEvent event) {Log.d("test","MainActivity got message:" + event);//start update language}@Overrideprotected void onDestroy(){super.onDestroy();EventBus.getDefault().unregister(this);//反注册EventBus}
}
步骤6
编写修改多语言文字的代码:
//给给出一个view,把子view全部检查一遍,如果是实现LanguageView接口的view,更新语言public static void updateViewLanguage(View view) {if (view instanceof ViewGroup) {ViewGroup vg = (ViewGroup) view;int count = vg.getChildCount();for (int i = 0; i < count; i++) {updateViewLanguage(vg.getChildAt(i));}} else if (view instanceof LanguageView) {LanguageView tv = (LanguageView) view;tv.reLoadLanguage();}}
修改多语言文字的代码写好后,开始调用:
@Subscribe(threadMode = ThreadMode.MAIN) //在ui线程执行public void onStringEvent(ClassEvent event) {Log.d("test","MainActivity got message:" + event);ViewUtil.updateViewLanguage(findViewById(android.R.id.content));}
最后点一下按钮就能更新语言了,activity没有重启,而且上一个activity的语言也跟着改变,不需要自己找出textview手动修改,是不是很方便呢?!
最后给出demo代码:
gitDemo
这篇关于android程序内多语言切换不需要重新启动的解决方案的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!