android 应用内切换语言

您所在的位置:网站首页 安卓多语言 android 应用内切换语言

android 应用内切换语言

2023-10-07 17:37| 来源: 网络整理| 查看: 265

一:创建不同语言的strings.xml

1.1 选中res,右键选择Android Resource Directory => Locale => >> 选择你需要的语言 1.2 将values下的strings.xml复制到对应语言下的values下 1.3 将不同strings.xml中的内容改成对应的语言文字,不同strings.xml中同一个内容的name是相同的 1.4 在布局文件或者代码中引用strings.xml里的内容 我选择了英文和繁体中文,创建好后如下图所示在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

二:代码切换语言

android N以下,需要在application的onCreate里切换Locale,N及以上,在Activity的attachBaseContext去切换即可 实现代码如下

2.1 创建LocaleUtils文件

/** * 如果是7.0以下,我们需要调用changeAppLanguage方法, * 如果是7.0及以上系统,直接把我们想要切换的语言类型保存起来,在baseActivity中切换 * 然后重新启动MainActivity * @param locale * @param context */ public static void changeAppLanguage(Locale locale,Context context){ DisplayMetrics metrics = context.getResources().getDisplayMetrics(); Configuration configuration = context.getResources().getConfiguration(); if ((Build.VERSION.SDK_INT if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { return updateResources(context); } return context; } @RequiresApi(Build.VERSION_CODES.N) private static Context updateResources(Context context) { Locale locale = HawkUtil.INSTANCE.getLocale(); Configuration configuration = context.getResources().getConfiguration(); configuration.setLocale(locale); configuration.setLocales(new LocaleList(locale)); return context.createConfigurationContext(configuration); }

2.2 自定义Application

class MyApplication : Application() { override fun onCreate() { super.onCreate() Hawk.init(this).build() /** * 对于7.0以下,需要在Application创建的时候进行语言切换 */ val locale = HawkUtil.getLocale() LocaleUtils.changeAppLanguage(locale,this) } /** * 系统切换语言时,会回调次方法 */ override fun onConfigurationChanged(newConfig: Configuration) { super.onConfigurationChanged(newConfig) val locale = HawkUtil.getLocale() Locale.setDefault(locale) LocaleUtils.changeAppLanguage(locale,this) } }

2.3 创建BaseActivity

open class BaseActivity : AppCompatActivity() { /** * 此方法先于 onCreate()方法执行 * @param newBase */ override fun attachBaseContext(newBase: Context?) { /** * attach对应语言环境下的context */ super.attachBaseContext(LocaleUtils.attachBaseContext(newBase)) } }

2.4 将MainActivity继承BaseActivity

class MainActivity : BaseActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) findViewById(R.id.btn_simplified).setOnClickListener { switchAppLanguage(Locale.SIMPLIFIED_CHINESE) } findViewById(R.id.btn_traditional).setOnClickListener { switchAppLanguage(Locale.TRADITIONAL_CHINESE) } findViewById(R.id.btn_english).setOnClickListener { switchAppLanguage(Locale.US) } } private fun switchAppLanguage(locale: Locale){ LocaleUtils.changeAppLanguage(locale,this) val intent = Intent(this, MainActivity::class.java) intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK startActivity(intent) } }

上面的代码代码只是可以切换语言,只适用于单页面,Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK会清掉任务栈里的activity实例,再将MainActivity的实例添加到新的任务栈。

在我实际的项目中,登录页面也可以进入到切换语言页面,而所有需要登录后才能操作的地方都可以进入到登录页,这样就需要保留任务栈。这时就不能直接用 2.4中switchAppLanguage()的方法了

在2.3中,在baseActivity中重写attachBaseContext(), 在切换语言后,已启动的activity会回调次方法。新启动的activity也会在onCreate()回调前先回调attachBaseContext(),所以需要考虑怎么让已有任务栈里的activity回调attachBaseContext()

我的做法是 自己维护一个任务栈,选择了相应的语言点击保存后。遍历自己维护的任务栈,调用activity的recreate()方法,代码如下

private fun finishPage(){ //当前页面不recreate,不然会有闪退那样的闪一下 AppManager.getInstance().activityStack.forEach { if (it !is SelectLanguageActivity){ it.recreate() } } //别的activity recreate完,finish掉当前页面,返回到进入切换语言的页面 finish() }

注意,调用activity的recreate(),activity及view需要做好状态保存和恢复。

上面这样切换,在Android7的系统上会有问题 现在暂时的做法是在BaseActivity上重写getResources()方法 具体看如下代码

@Override public Resources getResources() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && Build.VERSION.SDK_INT return super.getResources(); } } @Override protected void attachBaseContext(Context newBase) { Context cc = LocaleUtil.INSTANCE.changeLang(newBase); super.attachBaseContext(cc); }

LogcaleUtil.changeLang()的代码如下

fun changeLang(context: Context): Context{ val res = context.resources val config = res.configuration val locale: Locale = HawkUtil.getLocale() if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){ config.setLocale(locale) config.setLocales(LocaleList(locale)) }else{ config.locale = locale } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1){ config.setLayoutDirection(locale) return ContextWrapper(context.createConfigurationContext(config)) }else{ context.resources.updateConfiguration(config,res.displayMetrics) return ContextWrapper(context) } }

打包aab发布到google play上,用户下载下来切换多语言可能会失败 设置多语言不分包处理可解决 在app级gradle中,Android-defuultConfig中添加如下代码

bundle { language { //多语言不分包处理 enableSplit = false } density { // This property is set to true by default. enableSplit = true } abi { // This property is set to true by default. enableSplit = true } }


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3