Android:如何以编程方式更改应用语言? [英] Android: How to change app language programmatically?

查看:61
本文介绍了Android:如何以编程方式更改应用语言?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想以编程方式更改我的应用语言.我有一些适用于旧手机(Android 6)的代码,但不适用于 Android 8 和 Android 9.任何适用于应用语言更改的有效解决方案?调用setLocal之后,我在Activity中调用recreate().字符串仍然没有变化.

I want to change my app language programatically. I have some code which is working on older phones ( Android 6) but it is not working on Android 8 and Android 9. Any working solution for app language change? After calling setLocal I call recreate() inside Activity. Still no changes in strings.

在我的 MainActivity 中,该扩展了 onCreate()中的 BaseActivity ,如果我调用 Locale.getDefault().language 它返回正确的语言代码,但是字符串仍然是英语,这是默认的 string.xml .

In my MainActivity which is extending BaseActivity in onCreate() If I call Locale.getDefault().language it is returning correct language code but strings are still in English which is default string.xml.

fun setLocale(context: Context, language: String?): Context {
    app.setLanguage(language)

    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        updateResources(context, language)
    } else updateResourcesLegacy(
        context,
        language
    )

}

@TargetApi(Build.VERSION_CODES.N)
private fun updateResources(context: Context, language: String?): Context {
    val locale =
    if (language == null){
        Locale(Locale.getDefault().language)
    } else {
        Locale(language)
    }

    Locale.setDefault(locale)
    val configuration = context.resources.configuration
    configuration.setLocale(locale)

    return context.createConfigurationContext(configuration)
}

@Suppress("DEPRECATION")
private fun updateResourcesLegacy(context: Context, language: String?): Context {
    val locale =
        if (language == null){
            Locale(Locale.getDefault().language)
        } else {
            Locale(language)
        }

    Locale.setDefault(locale)
    val resources = context.resources

    val configuration = resources.configuration
    configuration.locale = locale

    resources.updateConfiguration(configuration, resources.displayMetrics)

    return context
}

更新:Ive在下面使用了两种解决方案的组合,但是仍然没有成功.我制作了 BaseActivity 类,该类在我的所有活动中得到了扩展.然后我调用 changeLocale 函数,该函数类似于LocaleHelper. app.getSavedLanguage()返回我的 sharedPrefs 中保存的语言代码.根据用户在应用中选择的语言,此代码将被覆盖.App是正在使用共享首选项的Application类.

UPDATE: Ive used combination of both solutions below, but still without success. I made BaseActivity class which is extended by all of my activities. And there I call changeLocale function which is similar to LocaleHelper. app.getSavedLanguage() returns saved language code in my sharedPrefs. This code is overwritten based on which language user choose in app. App is Application class which is working with shared preferences.

override fun onCreate(si: Bundle?) {
        super.onCreate(si)
        app = application as App
        changeLocale(this, app.getSavedLanguage())
    }

    open fun changeLocale(context: Context, lang: String) {
        val newLocale = Locale(lang)
        Locale.setDefault(newLocale)

        val res: Resources = context.resources
        val conf: Configuration = res.configuration

        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
            conf.apply {
                setLocale(newLocale)
                setLayoutDirection(newLocale)
            }

            context.createConfigurationContext(conf)
        } else {
            conf.apply {
                locale = newLocale
                setLayoutDirection(newLocale)
            }

            res.updateConfiguration(conf, res.displayMetrics)
        }
    }

推荐答案

我遇到了同样的问题,对于希伯来语和阿拉伯语用户,我总是需要从右向左固定屏幕.经过无数次尝试,我提出了建议的解决方案:

I had the same problem, I always needed to pin the screen from right to left for users in Hebrew and Arabic. After countless attempts, I came up with the suggested solution:

创建基本活动并从此类扩展您的活动.

Create base Activity and extends your activities from this class.

import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.DisplayMetrics;
import android.view.View;

import java.util.Locale;

public abstract class Activity_Base extends AppCompatActivity {

    int q = 0;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        changeLocale(this, "iw");


        Resources res = getResources();
        // Change locale settings in the app.
        DisplayMetrics dm = res.getDisplayMetrics();
        android.content.res.Configuration conf = res.getConfiguration();
        conf.setLocale(new Locale("iw")); // API 17+ only.
        // Use conf.locale = new Locale(...) if targeting lower versions
        res.updateConfiguration(conf, dm);


        getWindow().getDecorView().setLayoutDirection(View.LAYOUT_DIRECTION_RTL);

        Locale locale = new Locale("iw");
        Locale.setDefault(locale);
        Configuration config = new Configuration();
        config.locale = locale;
        getApplicationContext().getResources().updateConfiguration(config, getApplicationContext().getResources().getDisplayMetrics());

        super.onCreate(savedInstanceState);
    }

    public static void changeLocale(Context context, String locale) {
        Resources res = context.getResources();
        Configuration conf = res.getConfiguration();
        conf.locale = new Locale(locale);
        res.updateConfiguration(conf, res.getDisplayMetrics());
    }
}

使用 - 只是扩展您的活动:

Using - just extends your activity:

public class Activity_Article extends Activity_Base {

这篇关于Android:如何以编程方式更改应用语言?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆