android 应用内切换语言

这篇具有很好参考价值的文章主要介绍了android 应用内切换语言。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一:创建不同语言的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 应用内切换语言
android 应用内切换语言
android 应用内切换语言
android 应用内切换语言

二:代码切换语言

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 < Build.VERSION_CODES.N)){
            configuration.setLocale(locale);
        }
        context.getResources().updateConfiguration(configuration,metrics);
        HawkUtil.INSTANCE.saveLocale(locale);
    }

    public static Context attachBaseContext(Context context){
        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<Button>(R.id.btn_simplified).setOnClickListener {
            switchAppLanguage(Locale.SIMPLIFIED_CHINESE)
        }
        findViewById<Button>(R.id.btn_traditional).setOnClickListener {
            switchAppLanguage(Locale.TRADITIONAL_CHINESE)
        }
        findViewById<Button>(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 < Build.VERSION_CODES.O){
		Context cc = LocaleUtil.INSTANCE.changeLang(getApplicationContext());
        return cc.getResources();
	}else {
    	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中添加如下代码文章来源地址https://www.toymoban.com/news/detail-400577.html

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
	}
}

到了这里,关于android 应用内切换语言的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android studio TCP网络调试助手应用开发(支持TCP Server与Client切换)

            在前几篇的文章中带大家完成了 基于TCP的物联网安卓应用开发 ,教程内容是创建了一个 TCP客户端并连接服务器完成数据通信的过程 ,后不久又发布了一个 ESP8266创建TCP 服务器与安卓的客户端进行通信 的一个文章,当时在文章中提到“如果大家有需要将ESP8266配置

    2024年02月06日
    浏览(67)
  • Android studio创建新的工程时没有语言选项

    用新的Android studio创建工程时有时候会遇到没有语言选项,默认创建的工程是kotlin语言。 这时我们可以创建别的工程比如Empty view Activity 可以看到这时候就有语言选项

    2024年02月11日
    浏览(70)
  • 【Flutter】使用Android Studio 创建第一个flutter应用。

    首先下载好 flutter sdk和 Android Studio。 FlutterSDK下载 Android Studio官网 我的是 windows。 查看flutter安装环境。 如果没有,自己在环境变量的path添加下flutter安装路径。 在将 Path 变量更新后,打开一个新的控制台窗口,然后执行下面的命令。如果它提示有任何的平台相关依赖,那么

    2024年02月10日
    浏览(65)
  • 2022.3.1 Android studio创建新的工程时没有语言选项

    在使用新版Android studio创建Empty Activity工程时会遇到没有语言选项,默认创建的工程是kotlin语言。  这时我们可以选择Empty Views Activity点击next 在这里我们就可以把Language更改为Java

    2024年02月09日
    浏览(44)
  • Google推出Telecom Jetpack库,让Android通话应用创建更简单

    Telecom Jetpack库的最新Alpha版本已经推出。该库提供了多个API,以简化Android开发者创建语音和/或视频通话应用程序的过程,支持常见功能,例如接听/拒绝、音频路由等等。 https://developer.android.google.cn/jetpack/androidx/releases/core?hl=zh-cn#core-telecom_version_10_2 首先,新库会处理声明前台

    2024年01月22日
    浏览(60)
  • 【干货】Android系统定制基础篇:第二部分(Launcher3支持键盘切换焦点、开发者模式密码确认、禁止非预装应用安装、配置时间)

    Android Launcher3 默认并不支持键盘操作,无法切换焦点,在一些需要支持键盘或遥控操作的设备中无法使用,因些对 Launcher3 做简单修改,使其支持键盘切换焦点。 在安全性要求比较高的产品中,一般会默认关闭『adb调试』,同时禁止用户打开『adb调试』功能。在Android8.1中默认

    2024年02月10日
    浏览(55)
  • android studio创建一个新的项目为什么默认是kotlin语言而选择不了java语言

    关于android studio语言选择的问题。 我在进入android studio为什么创建一个新项目之后选择不了java语言有什么办法可以解决。 解决办法:这个模式下选着一个Empty Activity模块就可以使用java语言。 这对于刚刚接触anaroid studio新手比较管用。  

    2024年02月11日
    浏览(57)
  • tab点击切换不使用判断条件进行不同tab的切换刷新

    注:我这里使用的antd vue ui

    2024年02月09日
    浏览(47)
  • Python不同版本之间的切换方法

    这篇文章以3.11.0与3.10.10之间的版本切换为列讲述 首先我自己的电脑上同时安装了这两个版本的Python,并且都已经配置了环境变量 1.两个版本的Python 2.环境变量 调出CMD(win+r,输入cmd,回车),输入python,可以看到目前的版本为3.10.10 注意:这样在直接使用pip安装库的时候是安

    2024年02月03日
    浏览(56)
  • vue3中如何实现通过点击不同的按钮切换不同的页面

    完成以上需求,我们可以使用vue中的component标签来实现。 component是Vue.js中一个特殊的标签,用于动态地绑定其它组件。它可以与v-bind:is指令一起使用,来决定要渲染哪个组件。下面是示例代码

    2024年02月09日
    浏览(54)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包