android程序内多语言切换不需要重新启动的解决方案

本文主要是介绍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程序内多语言切换不需要重新启动的解决方案的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/994042

相关文章

从基础到高级详解Go语言中错误处理的实践指南

《从基础到高级详解Go语言中错误处理的实践指南》Go语言采用了一种独特而明确的错误处理哲学,与其他主流编程语言形成鲜明对比,本文将为大家详细介绍Go语言中错误处理详细方法,希望对大家有所帮助... 目录1 Go 错误处理哲学与核心机制1.1 错误接口设计1.2 错误与异常的区别2 错误创建与检查2.1 基础

java程序远程debug原理与配置全过程

《java程序远程debug原理与配置全过程》文章介绍了Java远程调试的JPDA体系,包含JVMTI监控JVM、JDWP传输调试命令、JDI提供调试接口,通过-Xdebug、-Xrunjdwp参数配... 目录背景组成模块间联系IBM对三个模块的详细介绍编程使用总结背景日常工作中,每个程序员都会遇到bu

Go语言中json操作的实现

《Go语言中json操作的实现》本文主要介绍了Go语言中的json操作的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录 一、jsOChina编程N 与 Go 类型对应关系️ 二、基本操作:编码与解码 三、结构体标签(Struc

uni-app小程序项目中实现前端图片压缩实现方式(附详细代码)

《uni-app小程序项目中实现前端图片压缩实现方式(附详细代码)》在uni-app开发中,文件上传和图片处理是很常见的需求,但也经常会遇到各种问题,下面:本文主要介绍uni-app小程序项目中实... 目录方式一:使用<canvas>实现图片压缩(推荐,兼容性好)示例代码(小程序平台):方式二:使用uni

python语言中的常用容器(集合)示例详解

《python语言中的常用容器(集合)示例详解》Python集合是一种无序且不重复的数据容器,它可以存储任意类型的对象,包括数字、字符串、元组等,下面:本文主要介绍python语言中常用容器(集合... 目录1.核心内置容器1. 列表2. 元组3. 集合4. 冻结集合5. 字典2.collections模块

Redis高性能Key-Value存储与缓存利器常见解决方案

《Redis高性能Key-Value存储与缓存利器常见解决方案》Redis是高性能内存Key-Value存储系统,支持丰富数据类型与持久化方案(RDB/AOF),本文给大家介绍Redis高性能Key-... 目录Redis:高性能Key-Value存储与缓存利器什么是Redis?为什么选择Redis?Red

基于Go语言开发一个 IP 归属地查询接口工具

《基于Go语言开发一个IP归属地查询接口工具》在日常开发中,IP地址归属地查询是一个常见需求,本文将带大家使用Go语言快速开发一个IP归属地查询接口服务,有需要的小伙伴可以了解下... 目录功能目标技术栈项目结构核心代码(main.go)使用方法扩展功能总结在日常开发中,IP 地址归属地查询是一个常见需求:

Android实现图片浏览功能的示例详解(附带源码)

《Android实现图片浏览功能的示例详解(附带源码)》在许多应用中,都需要展示图片并支持用户进行浏览,本文主要为大家介绍了如何通过Android实现图片浏览功能,感兴趣的小伙伴可以跟随小编一起学习一... 目录一、项目背景详细介绍二、项目需求详细介绍三、相关技术详细介绍四、实现思路详细介绍五、完整实现代码

在Android中使用WebView在线查看PDF文件的方法示例

《在Android中使用WebView在线查看PDF文件的方法示例》在Android应用开发中,有时我们需要在客户端展示PDF文件,以便用户可以阅读或交互,:本文主要介绍在Android中使用We... 目录简介:1. WebView组件介绍2. 在androidManifest.XML中添加Interne

线上Java OOM问题定位与解决方案超详细解析

《线上JavaOOM问题定位与解决方案超详细解析》OOM是JVM抛出的错误,表示内存分配失败,:本文主要介绍线上JavaOOM问题定位与解决方案的相关资料,文中通过代码介绍的非常详细,需要的朋... 目录一、OOM问题核心认知1.1 OOM定义与技术定位1.2 OOM常见类型及技术特征二、OOM问题定位工具