最近公司开始做多语言版本,由于之前没有做过,所以在网上搜寻了一番这方面的资料,最后经过实践、总结,写下了这篇文章。

效果图

实现

1. 创建对应语言的 string.xml 简体中文,繁体和 English 三个语言。

2. MultiLanguage.java

public class MultiLanguage {private static LanguageListener languageLocalListener;public static void init(LanguageListener listener) {languageLocalListener = listener;}public static Context setLocal(Context context) {return updateResources(context, getSetLanguageLocale(context));}/*** 设置语言类型*/public static void setApplicationLanguage(Context context) {Resources resources = context.getApplicationContext().getResources();DisplayMetrics dm = resources.getDisplayMetrics();Configuration config = resources.getConfiguration();Locale locale = getSetLanguageLocale(context);config.locale = locale;if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {LocaleList localeList = new LocaleList(locale);LocaleList.setDefault(localeList);config.setLocales(localeList);context.getApplicationContext().createConfigurationContext(config);Locale.setDefault(locale);}resources.updateConfiguration(config, dm);}/*** @param context*/public static void onConfigurationChanged(Context context) {setLocal(context);setApplicationLanguage(context);}/*** 获取选择的语言** @param context* @return*/private static Locale getSetLanguageLocale(Context context) {if (languageLocalListener != null) {return languageLocalListener.getSetLanguageLocale(context);}return Locale.ENGLISH;}/*** 更新语言设置** @param context* @param locale* @return*/private static Context updateResources(Context context, Locale locale) {Locale.setDefault(locale);Resources res = context.getResources();Configuration config = new Configuration(res.getConfiguration());if (Build.VERSION.SDK_INT >= 17) {config.setLocale(locale);context = context.createConfigurationContext(config);} else {config.locale = locale;res.updateConfiguration(config, res.getDisplayMetrics());}return context;}/*** 获取系统语言* @param newConfig* @return*/public static Locale getSystemLocal(Configuration newConfig) {Locale locale;if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {locale = newConfig.getLocales().get(0);} else {locale = newConfig.locale;}return locale;}/*** 获取系统语言* @param context* @return*/public static Locale getSystemLocal(Context context) {Locale locale;if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {locale = LocaleList.getDefault().get(0);} else {locale = Locale.getDefault();}return locale;}
}

3. SPUtil.java

public class SPUtil {private final String SP_NAME = "language_setting";private final String TAG_LANGUAGE = "language_select";private final String TAG_SYSTEM_LANGUAGE = "system_language";private static volatile SPUtil instance;private final SharedPreferences mSharedPreferences;private Locale systemCurrentLocal = Locale.ENGLISH;public SPUtil(Context context) {mSharedPreferences = context.getSharedPreferences(SP_NAME, Context.MODE_PRIVATE);}public void saveLanguage(int select) {SharedPreferences.Editor edit = mSharedPreferences.edit();edit.putInt(TAG_LANGUAGE, select);edit.commit();}public int getSelectLanguage() {return mSharedPreferences.getInt(TAG_LANGUAGE, 0);}public Locale getSystemCurrentLocal() {return systemCurrentLocal;}public void setSystemCurrentLocal(Locale local) {systemCurrentLocal = local;}public static SPUtil getInstance(Context context) {if (instance == null) {synchronized (SPUtil.class) {if (instance == null) {instance = new SPUtil(context);}}}return instance;}
}

4. LanguageUtils.java

public class LanguageUtils {private static final String TAG = "LocalManageUtil";/*** 获取系统的locale** @return Locale对象*/public static Locale getSystemLocale(Context context) {return SPUtil.getInstance(context).getSystemCurrentLocal();}public static String getSelectLanguage(Context context) {switch (SPUtil.getInstance(context).getSelectLanguage()) {case 0:return context.getString(R.string.language_auto);case 1:return context.getString(R.string.language_cn);case 2:return context.getString(R.string.language_traditional);case 3:default:return context.getString(R.string.language_en);}}/*** 获取选择的语言设置** @param context* @return*/public static Locale getSetLanguageLocale(Context context) {switch (SPUtil.getInstance(context).getSelectLanguage()) {case 0:return getSystemLocale(context);case 1:return Locale.CHINA;case 2:return Locale.TAIWAN;case 3:default:return Locale.ENGLISH;}}public static void saveSystemCurrentLanguage(Context context) {SPUtil.getInstance(context).setSystemCurrentLocal(MultiLanguage.getSystemLocal(context));}/*** 保存系统语言* @param context* @param newConfig*/public static void saveSystemCurrentLanguage(Context context, Configuration newConfig) {SPUtil.getInstance(context).setSystemCurrentLocal(MultiLanguage.getSystemLocal(newConfig));}public static void saveSelectLanguage(Context context, int select) {SPUtil.getInstance(context).saveLanguage(select);MultiLanguage.setApplicationLanguage(context);}
}

5. LanguageListener.java

public interface LanguageListener {/*** 获取选择设置语言** @param context* @return*/Locale getSetLanguageLocale(Context context);
}

6. LauncherApp.java

public class LauncherApp extends Application {@Overrideprotected void attachBaseContext(Context base) {//第一次进入app时保存系统选择语言(为了选择随系统语言时使用,如果不保存,切换语言后就拿不到了)LanguageUtils.saveSystemCurrentLanguage(base);super.attachBaseContext(MultiLanguage.setLocal(base));}@Overridepublic void onConfigurationChanged(Configuration newConfig) {super.onConfigurationChanged(newConfig);//用户在系统设置页面切换语言时保存系统选择语言(为了选择随系统语言时使用,如果不保存,切换语言后就拿不到了)LanguageUtils.saveSystemCurrentLanguage(getApplicationContext(), newConfig);MultiLanguage.onConfigurationChanged(getApplicationContext());}@Overridepublic void onCreate() {super.onCreate();MultiLanguage.init(new LanguageListener() {@Overridepublic Locale getSetLanguageLocale(Context context) {//返回自己本地保存选择的语言设置return LanguageUtils.getSetLanguageLocale(context);}});MultiLanguage.setApplicationLanguage(this);}
}

7. 布局文件

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@string/text"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent" /></androidx.constraintlayout.widget.ConstraintLayout>

在线工具

在线转换工具:中文转繁体

Android 项目必备(二十一)-->APP 多语言切换(国际化)相关推荐

  1. Android 项目必备(十一)--> 轮询操作

    文章目录 前言 实战 前言 什么叫轮询请求? 简单理解就是 App 端每隔一定的时间重复请求的操作就叫做轮询请求,比如:App 端每隔一段时间上报一次定位信息,App 端每隔一段时间拉去一次用户状态等 ...

  2. 【Android项目实战 | 从零开始写app(十二)】实现app首页智慧服务热门推荐热门主题、新闻

    说在前面,由于各种adapter,xml布局,bean实体类,Activity,也为了让看懂,代码基本都是"简单粗暴直接不好看",没啥okhttp和util工具类之类的封装,本篇幅 ...

  3. 【Android项目实战 | 从零开始写app (六) 】用TabLayout+ViewPager搭建App 框架主页面底部导航栏

    本篇实现效果: 搭建app框架的方式有很多,本节主要用TabLayout+ViewPager搭建App框架,这种方式简单易实现,在主页中加载Fragment碎片,实现不同功能页面的切换效果图如下: 文 ...

  4. 【Android项目实战 | 从零开始写app(十三)】实现用户中心模块清除token退出登录信息修改等功能

    五一后,被ji金伤了,哇呜呜,还是得苦逼老老实实打工写代码,看下面吧 本篇实现效果: 实现登录用户名展示到用户中心页面上,并且页面有个人信息,订单列表,修改密码,意见反馈发送到服务端,前面登录后,通过 ...

  5. 【Android项目实战 | 从零开始写app一一智慧服务】完结篇系列导航篇、源代码

    目录 文章介绍 涉及知识 系列汇总 项目源代码 文章介绍 本系列小文是一个简单的Android app项目实战,对于刚入门Android 的初学者来说,基础学完了,但是怎么综合的去写一个小app,可能 ...

  6. Android 面试必备 - 系统、App、Activity 启动过程

    前言 最近准备更新 Android 面试必备基础知识系列,有兴趣的可以关注我的微信公众号 stormjun94,有更新时,第一时间会在微信公众号上面发布,同时,也会同步在 GitHub 上面更新,如果 ...

  7. Android项目实战(四):ViewPager切换动画(3.0版本以上有效果)

    原文:Android项目实战(四):ViewPager切换动画(3.0版本以上有效果) 学习内容来自"慕课网" 一般APP进去之后都会有几张图片来导航,这里就学习怎么在这张图片切换 ...

  8. Android项目必备技术

    1.一个APP只需要一个Activity //片段fragmentimplementation 'me.yokeyword:fragmentation:1.3.6'implementation 'me ...

  9. Android项目实战:账本APP开发

    好好学习,天天向上 本文已收录至我的Github仓库DayDayUP:github.com/RobodLee/DayDayUP,欢迎Star,更多文章请前往:目录导航 Java项目实战:账本APP服务 ...

  10. app系统语言切换及app内部切换语言

    今天闲来无事看了点关于android系统语言及app内语言的切换,有点小感想就做了个demo,拿出来分享下 1.根据系统语言app适配 这个相对来说比较简单我们只需要建一个相应的values文件夹就好 ...

最新文章

  1. linux内核实验平台搭建,搭建自己的Linux实验系统(一)
  2. iOS之深入解析dyld与ObjC关联的底层原理
  3. linux创建用户,并修改分组,改变权限
  4. thymeleaf与jsp_PagingAndSortingRepository –如何与Thymeleaf一起使用
  5. 好全的Android面试题
  6. mysql备份表恢复数据库_mysql备份恢复数据库据/表
  7. 计算机视觉论文-2021-06-17
  8. 软考网络工程师学习笔记3-广域通信网
  9. 关于pidgin群显示NULL 解决办法
  10. [转载]document.readyState
  11. 深度学习论文写作框架
  12. 为什么Lisp语言如此先进?(译文)
  13. Ae 效果快速参考:沉浸式视频
  14. 自学HarmonyOS应用开发(64)- 处理屏幕旋转
  15. EMC电磁兼容测试服务包括
  16. idea中JD-Intellij插件如何使用以及Luyten的使用
  17. 为什么劝你别去创业?大抵逃不掉这 101 个问题
  18. POI实现Excel的导出
  19. 用户和计算机通信的界面设计,数据分析系统的交互界面设计
  20. coot 无法识别DNA/RNA的解决方法

热门文章

  1. Python日志管理工具:logging、logbook、Eliot、Raven和Sentry
  2. 测试适合染发颜色的软件,染发小测试 测出最适合自己的染发颜色
  3. 谷歌浏览器翻译失效--无法翻译此页面
  4. SQL Server中的数据字典
  5. 批量生成二维码——《超级处理器》应用
  6. 各大电商平台关键词、商品详情API、品牌情报与品牌保护、价格监控、竞价比价
  7. Python tkinter+turtle制作表白神器
  8. PLSQL安装完毕连接数据库问题记录
  9. 痞子衡嵌入式:大话双核i.MXRT1170之在线联合调试双核工程的三种方法(IAR篇)
  10. 没有兴趣爱好,该怎么回答面试官?