Android切换语言不退出App

1.需求

实现用户选择语言(未点击下一步),更新当前界面UI,点击下一步后,更新App的语言,并进行保存。

实现目标:

1.设置App的语言,本地进行保存

2.updateResources更新本地语言配置

2.实现代码

1.LanguageManager

object LanguageManager {private const val PREFS_NAME = "settings"private const val LANGUAGE_KEY = "language"fun setLanguage(context: Context, language: String) {// 保存语言到 SharedPreferencesval sharedPreferences = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)sharedPreferences.edit().putString(LANGUAGE_KEY, language).apply()// 更新资源updateResources(context, language)}fun getSavedLanguage(context: Context): String {// 如果没有保存语言,默认使用系统语言val sharedPreferences = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)return sharedPreferences.getString(LANGUAGE_KEY, Locale.getDefault().language) ?: Locale.getDefault().language}fun applyLanguage(context: Context): Context {// 获取保存的语言并更新 Contextval language = getSavedLanguage(context)return updateResources(context, language)}private fun updateResources(context: Context, language: String): Context {val locale = Locale(language)Locale.setDefault(locale)val configuration = Configuration(context.resources.configuration)configuration.setLocale(locale)return context.createConfigurationContext(configuration)}
}

2.所有的基类进行设置,记得application在manifest应用

class MyApplication : Application() {override fun attachBaseContext(base: Context) {// 应用保存的语言super.attachBaseContext(LanguageManager.applyLanguage(base))}override fun onConfigurationChanged(newConfig: Configuration) {super.onConfigurationChanged(newConfig)// 当配置改变时(如系统语言切换),重新应用用户选择的语言LanguageManager.applyLanguage(this)}
}

BaseActivity

所有 Activity 自动应用语言配置:

open class BaseActivity : AppCompatActivity() {override fun attachBaseContext(newBase: Context) {// 为每个 Activity 更新语言配置super.attachBaseContext(LanguageManager.applyLanguage(newBase))}
}
open class BaseFragment : Fragment() {override fun onAttach(context: Context) {super.onAttach(LanguageManager.applyLanguage(context))  // 在这里更新语言}
}

3.为什么还要在 Activity 里设置语言?

通常,在 ActivityFragment 中设置语言是为了在运行时动态更新语言,尤其是当用户切换语言后,某些界面可能需要重新加载来反映新的语言设置。

关键点:

  1. Application 中设置语言:可以在应用启动时统一设置默认语言,确保语言配置在整个应用中生效。
  2. ActivityFragment 中设置语言:可以在用户选择语言并希望立即看到语言更改时,确保当前 ActivityFragment 界面更新。

4.在当前页动态修改语言设置,动态修改文案,但是不点击下一步时,不保存语言选择。

   private fun updateLanguage(languageCode: String) {LogUtils.e("updateLanguage", languageCode)val finalCode: String = languageCodeval locale =if (languageCode == AppConstants.ZH_HANS) {Locale("zh","CN")} else if (languageCode == AppConstants.ZH_HANT) {Locale("zh","TW")} else Locale(finalCode)Locale.setDefault(locale)  // 设置默认语言val config = Configuration(resources.configuration)config.setLocale(locale)  // 修改当前界面语言// 创建新的 Context,并应用新的 Configurationval localizedContext = createConfigurationContext(config)// 将新的 Context 应用于当前页面的 UIval resources = localizedContext.resourcesval displayMetrics = resources.displayMetricsresources.updateConfiguration(config, displayMetrics)// 使用新的语言设置刷新当前界面initData(localizedContext)  //界面将刷新以应用新的语言}

5.其余关键点

1.既然只刷新当前UI,就得生成新的context

localizedContext = createConfigurationContext(config)

2.initData里面就是数据赋值渲染UI,如果调用Activity的recreate方法会闪退,别调用。

6.保存设置退出App

需求:点击语言后,保存语言设置,并且退出App

//点击事件
binding.langCl.setOnClickListener {diaLog = LanguageBottomSheetFragment { selectedLanguage ->lifecycleScope.launch {LogUtils.e("onLanguageSelected", selectedLanguage)val saveSuccess = saveLanguageSuspend(requireContext(), selectedLanguage)if (saveSuccess) {diaLog?.binding?.root?.isEnabled = falsediaLog?.dismiss() // 关闭弹窗restartApp()} else {LogUtils.e("saveLanguage", "Failed to save language")}}}diaLog?.show(parentFragmentManager, "LanguageBottomSheet")
//             VIPBottomSheetFragment().show(parentFragmentManager, "VIPBottomSheet")}//保证保存成功suspend fun saveLanguageSuspend(context: Context, language: String): Boolean {return suspendCancellableCoroutine { continuation ->val sharedPreferences =context.getSharedPreferences(BaseApp.PREFS_NAME, Context.MODE_PRIVATE)val success = sharedPreferences.edit().putString(LANGUAGE_KEY, language).commit()continuation.resume(success)}}

tips:

1、**suspendCancellableCoroutine** 是 Kotlin 中用于将回调或异步操作转化为挂起函数的工具。它是挂起函数的一部分,可以与协程一起工作,并且能够在协程上下文被取消时进行适当的处理。

2、continuation.resume(success) 将保存结果恢复给挂起函数调用者。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/65861.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一键获取Linux主机配置信息shell脚本,含网卡详情,网卡绑定等

cat > /tmp/get_os_info.sh <<"EOF"#!/bin/bashexport LANG=en_US.UTF-8# 如果 cat /proc/1/cgroup | grep docker | wc -l 大于0 或 systemd-detect-virt 返回 docker,则为 docker容器,# 如果 virt-what 返回 kvm或vmware或hyperv或xen、xen-hvm、lxc 或…

2 XDMA IP中断

三种中断 1. Legacy 定义&#xff1a;Legacy 中断是传统的中断处理方式&#xff0c;使用物理中断线&#xff08;例如 IRQ&#xff09;来传递中断信号。缺点&#xff1a; 中断线数量有限&#xff0c;通常为 16 条&#xff0c;限制了可连接设备的数量。中断处理可能会导致中断风…

【算法】时间复杂度以及O(N^2)的排序

目录 1.常数时间的操作 2.时间复杂度 2.1.以选择排序为例 2.2.O(n^2)从何而来 2.3.冒泡排序 2.3.1.抑或运算 2.4.插入排序 3.二分法 3.1.局部最小 4.递归 4.1.递归行为时间复杂度的估计 1.常数时间的操作 一个操作如果和样本的数据量无关&#xff0c;每次都是固定时…

2021 年 3 月青少年软编等考 C 语言五级真题解析

目录 T1. 红与黑思路分析T2. 密室逃脱思路分析T3. 求逆序对数思路分析T4. 最小新整数思路分析T1. 红与黑 有一间长方形的房子,地上铺了红色、黑色两种颜色的正方形瓷砖。你站在其中一块黑色的瓷砖上,只能向相邻的黑色瓷砖移动。请写一个程序,计算你总共能够到达多少块黑色的…

C# 或 .NetCore 如何使用 NPOI 导出图片到 Excel 文件

今天在本文中&#xff0c;我们将尝试使用NPOI库将图像插入到 Excel 文件的特定位置。请将以下逻辑添加到您的写作方法中&#xff0c;在 Excel 文件中添加图像&#xff08;JPEG、PNG&#xff09;,我已经有一个示例 jpeg 文件 - Read-write-excel-npoi.jpg &#xff0c;我们将尝试…

【学习笔记】理解深度学习的基础:机器学习

1. 机器学习基础 1.1 机器学习的定义与重要性 定义&#xff1a;深度学习是机器学习的一种特定形式。为了深入理解深度学习&#xff0c;必须牢固掌握机器学习的基本原理。机器学习算法是一种能够从数据中学习的算法&#xff0c;通过经验E在任务T上提高性能度量P&#xff08;Mi…

Observability:将 OpenTelemetry 添加到你的 Flask 应用程序

作者&#xff1a;来自 Elastic jessgarson 待办事项列表可以帮助管理与假期计划相关的所有购物和任务。使用 Flask&#xff0c;你可以轻松创建待办事项列表应用程序&#xff0c;并使用 Elastic 作为遥测后端&#xff0c;通过 OpenTelemetry 对其进行监控。 Flask 是一个轻量级…

使用Matplotlib显示中文的方法

1 问题提出 使用图1所示的代码进行matplotlib绘图时&#xff0c;因为其默认不支持中文&#xff0c;此时无法显示正确内容&#xff0c;如图2所示。 图1 matplotlib绘图绘图代码 图2 matplotlib无法显示中文 2 问题解决 2.1 设置全局字体 在图1所示的代码中&#xff0c;第13…

详解opencv resize之INTER_LINEAR和INTER_AREA

一。先简单介绍一下resize的用法 src&#xff1a;输入图&#xff0c; dst&#xff1a;输出图 dsize&#xff1a;输出图的宽高&#xff0c;如果dsize不为空&#xff08;即宽高都不是0&#xff09;&#xff0c;则以dsize为准进行resize。 fx, fy是放大缩小的比例&#xff0c;是…

UnityDemo-TheBrave-制作笔记

这是我跟着b站up主MStudio的视频学习制作的&#xff0c;大体上没有去做一些更新的东西&#xff0c;这里只是一个总的总结。在文章的最后&#xff0c;我会放上可以游玩该游戏的链接和exe可执行文件&#xff0c;不过没有对游戏内容进行什么加工&#xff0c;只有基本的功能实现罢了…

使用LSTM预测股票收盘价

在金融数据预测中&#xff0c;LSTM&#xff08;长短期记忆网络&#xff09;凭借其在时间序列数据建模中的优势&#xff0c;成为了分析股票价格趋势的热门选择。本篇博客将以完整的代码实现为例&#xff0c;展示如何利用LSTM网络对股票收盘价进行预测&#xff0c;并从数据处理到…

模拟SpringIOCAOP

一、IOC容器 Ioc负责创建&#xff0c;管理实例&#xff0c;向使用者提供实例&#xff0c;ioc就像一个工厂一样&#xff0c;称之为Bean工厂 1.1 Bean工厂的作用 先分析一下Bean工厂应具备的行为 1、需要一个获取实例的方法&#xff0c;根据一个参数获取对应的实例 getBean(…

预编译SQL

预编译SQL 预编译SQL是指在数据库应用程序中&#xff0c;SQL语句在执行之前已经通过某种机制&#xff08;如预编译器&#xff09;进行了解析、优化和准备&#xff0c;使得实际执行时可以直接使用优化后的执行计划&#xff0c;而不需要每次都重新解析和编译。这么说可能有一些抽…

Centos9 + Docker 安装 MySQL8.4.0 + 定时备份数据库到本地

Centos9 + Docker 安装 MySQL8.4.0 + 定时备份数据库到本地 创建目录,创建配置文件启动容器命令定时备份MySQL执行脚本Linux每日定时任务命令文件内参数其他时间参数AT一次性定时任务创建目录,创建配置文件 $ mkdir -p /opt/mysql/conf$ vim /opt/mysql/conf/my.cnf[mysql] #…

软件测试预备知识⑥—搭建Web服务器

在软件测试的广阔领域中&#xff0c;搭建Web服务器是一项极为关键的技能。它不仅有助于模拟真实的应用环境&#xff0c;方便我们对Web应用进行全面且深入的测试&#xff0c;还能让测试人员更好地掌控测试场景&#xff0c;提升测试效率与质量。接下来&#xff0c;让我们一同深入…

计算机视觉算法实战——打电话行为检测

✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连✨ ​​​​​​​ ​​​​​​​​​​​​​​​ ​​​​​​ ​ 1. 引言✨✨ 随着智能手机的普及&#xff0c;打电话行为检测成为了计算机视…

事务的隔离级别和MDL

文章目录 说明不同隔离级别可能发生的现象关键现象解释MDL&#xff08;元数据锁&#xff0c;Metadata Lock&#xff09;MDL 的作用MDL 的工作原理MDL 锁的常见场景如何避免 MDL 阻塞 说明 本文章由大模型对话整理而来&#xff0c;如果有错误之处&#xff0c;请在评论区留言指正…

Linux第二课:LinuxC高级 学习记录day01

0、大纲 0.1、Linux 软件安装&#xff0c;用户管理&#xff0c;进程管理&#xff0c;shell 命令&#xff0c;硬链接和软连接&#xff0c;解压和压缩&#xff0c;功能性语句&#xff0c;结构性语句&#xff0c;分文件&#xff0c;make工具&#xff0c;shell脚本 0.2、C高级 …

单片机存储与计算机存储:从微小到庞大的数据世界

单片机存储与计算机存储&#xff1a;从微小到庞大的数据世界 在现代电子设备中&#xff0c;存储是至关重要的组成部分。无论是小巧的单片机&#xff0c;还是功能强大的计算机&#xff0c;存储都扮演着不可或缺的角色。然而&#xff0c;单片机和计算机的存储架构却有着天壤之别…

ISP流程--去马赛克详解

前言 本期我们将深入讨论ISP流程中的去马赛克处理。我们熟知&#xff0c;彩色图像由一个个像元组成&#xff0c;每个像元又由红、绿、蓝&#xff08;RGB&#xff09;三通道构成。而相机传感器只能感知光的强度&#xff0c;无法直接感知光谱信息&#xff0c;即只有亮暗而没有颜色…