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

相关文章

关于数据埋点,你需要了解这些基本知识

产品汪每天都在和数据打交道,你知道数据来自哪里吗? 移动app端内的用户行为数据大多来自埋点,了解一些埋点知识,能和数据分析师、技术侃大山,参与到前期的数据采集,更重要是让最终的埋点数据能为我所用,否则可怜巴巴等上几个月是常有的事。   埋点类型 根据埋点方式,可以区分为: 手动埋点半自动埋点全自动埋点 秉承“任何事物都有两面性”的道理:自动程度高的,能解决通用统计,便于统一化管理,但个性化定

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

科研绘图系列:R语言扩展物种堆积图(Extended Stacked Barplot)

介绍 R语言的扩展物种堆积图是一种数据可视化工具,它不仅展示了物种的堆积结果,还整合了不同样本分组之间的差异性分析结果。这种图形表示方法能够直观地比较不同物种在各个分组中的显著性差异,为研究者提供了一种有效的数据解读方式。 加载R包 knitr::opts_chunk$set(warning = F, message = F)library(tidyverse)library(phyl

透彻!驯服大型语言模型(LLMs)的五种方法,及具体方法选择思路

引言 随着时间的发展,大型语言模型不再停留在演示阶段而是逐步面向生产系统的应用,随着人们期望的不断增加,目标也发生了巨大的变化。在短短的几个月的时间里,人们对大模型的认识已经从对其zero-shot能力感到惊讶,转变为考虑改进模型质量、提高模型可用性。 「大语言模型(LLMs)其实就是利用高容量的模型架构(例如Transformer)对海量的、多种多样的数据分布进行建模得到,它包含了大量的先验

业务中14个需要进行A/B测试的时刻[信息图]

在本指南中,我们将全面了解有关 A/B测试 的所有内容。 我们将介绍不同类型的A/B测试,如何有效地规划和启动测试,如何评估测试是否成功,您应该关注哪些指标,多年来我们发现的常见错误等等。 什么是A/B测试? A/B测试(有时称为“分割测试”)是一种实验类型,其中您创建两种或多种内容变体——如登录页面、电子邮件或广告——并将它们显示给不同的受众群体,以查看哪一种效果最好。 本质上,A/B测

android-opencv-jni

//------------------start opencv--------------------@Override public void onResume(){ super.onResume(); //通过OpenCV引擎服务加载并初始化OpenCV类库,所谓OpenCV引擎服务即是 //OpenCV_2.4.3.2_Manager_2.4_*.apk程序包,存

EMLOG程序单页友链和标签增加美化

单页友联效果图: 标签页面效果图: 源码介绍 EMLOG单页友情链接和TAG标签,友链单页文件代码main{width: 58%;是设置宽度 自己把设置成与您的网站宽度一样,如果自适应就填写100%,TAG文件不用修改 安装方法:把Links.php和tag.php上传到网站根目录即可,访问 域名/Links.php、域名/tag.php 所有模板适用,代码就不粘贴出来,已经打

跨系统环境下LabVIEW程序稳定运行

在LabVIEW开发中,不同电脑的配置和操作系统(如Win11与Win7)可能对程序的稳定运行产生影响。为了确保程序在不同平台上都能正常且稳定运行,需要从兼容性、驱动、以及性能优化等多个方面入手。本文将详细介绍如何在不同系统环境下,使LabVIEW开发的程序保持稳定运行的有效策略。 LabVIEW版本兼容性 LabVIEW各版本对不同操作系统的支持存在差异。因此,在开发程序时,尽量使用