android 国际化切换语言_android studio切换中文[通俗易懂]

android 国际化切换语言_android studio切换中文[通俗易懂]老规矩,先上效果图图中分别展示了由应用内由中文切换到英文再到波斯语的展示

老规矩 ,先上效果图

这里写图片描述

图中分别展示了由应用内由中文切换到英文再到波斯语的展示。本篇博客介绍的两个点

  • 小语种的自定义
  • 应用内无感知切换语言

一、小语种的自定义

Java Locale 的语言常量基本囊括了主流语言:

    public static final Locale CANADA = null;
    public static final Locale CANADA_FRENCH = null;
    public static final Locale CHINA = null;
    public static final Locale CHINESE = null;
    public static final Locale ENGLISH = null;
    public static final Locale FRANCE = null;
    public static final Locale FRENCH = null;
    public static final Locale GERMAN = null;
    public static final Locale GERMANY = null;
    public static final Locale ITALIAN = null;
    public static final Locale ITALY = null;
    public static final Locale JAPAN = null;
    public static final Locale JAPANESE = null;
    public static final Locale KOREA = null;
    public static final Locale KOREAN = null;
    public static final Locale PRC = null;
    public static final char PRIVATE_USE_EXTENSION = 'x';
    public static final Locale ROOT = null;
    public static final Locale SIMPLIFIED_CHINESE = null;
    public static final Locale TAIWAN = null;
    public static final Locale TRADITIONAL_CHINESE = null;
    public static final Locale UK = null;
    public static final char UNICODE_LOCALE_EXTENSION = 'u';
    public static final Locale US = null;

目前 Java8 中我们可以看到,加拿大,中文,法语,德语,日语,意大利,韩国,英美等世界主流语言常量都支持。开始我是傻眼了波斯语没有对应的常量该如何是好?后来发现

new Locale( language, country , variant)

是可以支持自定义语言的

  • language
  • country
  • variant

language
ISO 639 alpha-2 or alpha-3 language code, or registered language subtags up to 8 alpha letters (for future enhancements). When a language has both an alpha-2 code and an alpha-3 code, the alpha-2 code must be used. You can find a full list of valid language codes in the IANA Language Subtag Registry (search for “Type: language”). The language field is case insensitive, but Locale always canonicalizes to lower case.

Well-formed language values have the form [a-zA-Z]{2,8}. Note that this is not the the full BCP47 language production, since it excludes extlang. They are not needed since modern three-letter language codes replace them.

Example: “en” (English), “ja” (Japanese), “kok” (Konkani)


country (region)
ISO 3166 alpha-2 country code or UN M.49 numeric-3 area code. You can find a full list of valid country and region codes in the IANA Language Subtag Registry (search for “Type: region”). The country (region) field is case insensitive, but Locale always canonicalizes to upper case.

Well-formed country/region values have the form [a-zA-Z]{2} | [0-9]{3}

Example: “US” (United States), “FR” (France), “029” (Caribbean)


variant
Any arbitrary value used to indicate a variation of a Locale. Where there are two or more variant values each indicating its own semantics, these values should be ordered by importance, with most important first, separated by underscore(‘_’). The variant field is case sensitive.

Note: IETF BCP 47 places syntactic restrictions on variant subtags. Also BCP 47 subtags are strictly used to indicate additional variations that define a language or its dialects that are not covered by any combinations of language, script and region subtags. You can find a full list of valid variant codes in the IANA Language Subtag Registry (search for “Type: variant”).
However, the variant field in Locale has historically been used for any kind of variation, not just language variations. For example, some supported variants available in Java SE Runtime Environments indicate alternative cultural behaviors such as calendar type or number script. In BCP 47 this kind of information, which does not identify the language, is supported by extension subtags or private use subtags.

Well-formed variant values have the form SUBTAG ((‘_’|’-‘) SUBTAG)* where SUBTAG = [0-9][0-9a-zA-Z]{3} | [0-9a-zA-Z]{5,8}. (Note: BCP 47 only uses hyphen (‘-‘) as a delimiter, this is more lenient).

Example: “polyton” (Polytonic Greek), “POSIX”

这种构造方式不得不说很**, 没有枚举 常量 自己去网上找对应的字符也不知道对不对

最好在网上找了些参考资料以及自己 debug 调试能够正确的切换到波斯语

private static final Locale Locale_Farsi = new Locale("FA", "fa", "");

这里写图片描述

二 应用内无感知切换语言

很多语言切换比较粗暴,直接杀死进程重启应用。或者跳转登录界面,上面演示图中的效果看上去就比较平顺。

    private void backToSettingActivity() {
        Intent mainActivity = new Intent(this, MainActivity.class);
        mainActivity.putExtra(MainActivity.INITIAL_TAB_INDEX, MainActivity.TAB_ME_INDEX);

        Intent settingActivity = new Intent(this, AccountSettingActivity.class);

        TaskStackBuilder taskStackBuilder = TaskStackBuilder.create(this);
        taskStackBuilder.addNextIntent(mainActivity);
        taskStackBuilder.addNextIntent(settingActivity);
        taskStackBuilder.startActivities();
        overridePendingTransition(0, 0);
    }

核心方法做的事情是记住栈的路径

提供一下完整代码:

public class ConfigurationManager { 
   
    private static boolean isInit = false;

    private ConfigurationManager() {

    }

    private static class SingletonHolder { 
   
        static ConfigurationManager sInstance = new ConfigurationManager();
    }


    private static class SystemConfigurationChangedReceiver extends BroadcastReceiver { 
   
        @Override
        public void onReceive(Context context, Intent intent) {
            if (Intent.ACTION_LOCALE_CHANGED.equals(intent.getAction())) {
                LangUtils.setSystemLocale(Locale.getDefault());
                LangUtils.RCLocale appLocale = LangUtils.getAppLocale(context);
                Locale systemLocale = LangUtils.getSystemLocale();
                if (!appLocale.toLocale().equals(systemLocale)) {
                    ConfigurationManager.getInstance().switchLocale(appLocale, context);
                }
            }
        }
    }

    public static ConfigurationManager getInstance() {
        return SingletonHolder.sInstance;
    }

    public static void init(Context context) {
        if (!isInit) {
            IntentFilter filter = new IntentFilter();
            filter.addAction(Intent.ACTION_LOCALE_CHANGED);
            context.registerReceiver(new SystemConfigurationChangedReceiver(), filter);

            //初始化时将应用语言重新设置为之前设置的语言
            RCLocale locale = ConfigurationManager.getInstance().getAppLocale(context);
            ConfigurationManager.getInstance().switchLocale(locale, context);
            isInit = true;
        }
    }


    public void switchLocale(RCLocale locale, Context context) {
        Resources resources = context.getResources();
        Configuration config = resources.getConfiguration();
        config.locale = locale.toLocale();
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
            context.getResources().updateConfiguration(config, resources.getDisplayMetrics());
        }
        LangUtils.saveLocale(context, locale);
    }


    public Context getConfigurationContext(Context context) {
        return LangUtils.getConfigurationContext(context);
    }


    public LangUtils.RCLocale getAppLocale(Context context) {
        return LangUtils.getAppLocale(context);
    }


    public Locale getSystemLocale() {
        return LangUtils.getSystemLocale();
    }
}
public class LangUtils { 
   

    private static final Locale Locale_Farsi = new Locale("FA", "fa", "");
    private static final String LOCALE_CONF_FILE_NAME = "locale.config";
    private static final String APP_LOCALE = "seal_app_locale";
    private static Locale systemLocale = Locale.getDefault();

    public static Context getConfigurationContext(Context context) {
        Resources resources = context.getResources();
        Configuration config = new Configuration(resources.getConfiguration());
        Context configurationContext = context;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            LocaleList localeList = new LocaleList(getAppLocale(context).toLocale());
            LocaleList.setDefault(localeList);
            config.setLocales(localeList);
            configurationContext = context.createConfigurationContext(config);
        }
        return configurationContext;
    }

    public static RCLocale getAppLocale(Context context) {
        SharedPreferences sp
                = context.getSharedPreferences(LOCALE_CONF_FILE_NAME, Context.MODE_PRIVATE);
        String locale = sp.getString(APP_LOCALE, "auto");
        Log.e("language get", locale);
        return RCLocale.valueOf(locale);
    }

    public static void saveLocale(Context context, RCLocale locale) {
        SharedPreferences sp
                = context.getSharedPreferences(LOCALE_CONF_FILE_NAME, Context.MODE_PRIVATE);
        Log.e("language save", locale.value());
        sp.edit().putString(APP_LOCALE, locale.value()).commit();
    }


    public static class RCLocale { 
   
        /** * 中文 */
        public static final RCLocale LOCALE_CHINA = new RCLocale("zh");
        /** * 英文 */
        public static final RCLocale LOCALE_US = new RCLocale("en");
        /** * 波斯 */
        public static final RCLocale LOCALE_FARSI = new RCLocale("fa");
        /** * 跟随系统 */
        public static final RCLocale LOCALE_AUTO = new RCLocale("auto");

        private String rcLocale;

        private RCLocale(String rcLocale) {
            this.rcLocale = rcLocale;
        }

        public String value() {
            return rcLocale;
        }

        public Locale toLocale() {
            Locale locale;
            if (rcLocale.equals(LOCALE_CHINA.value())) {
                locale = Locale.CHINESE;
            } else if (rcLocale.equals(LOCALE_US.value())) {
                locale = Locale.ENGLISH;
            } else if (rcLocale.equals(LOCALE_FARSI.value())) {
                locale = Locale_Farsi;
            } else {
                locale = getSystemLocale();
            }
            return locale;
        }

        public static RCLocale valueOf(String rcLocale) {
            RCLocale locale;
            if (rcLocale.equals(LOCALE_CHINA.value())) {
                locale = LOCALE_CHINA;
            } else if (rcLocale.equals(LOCALE_US.value())) {
                locale = LOCALE_US;
            } else if (rcLocale.equals(LOCALE_FARSI.value())) {
                locale = LOCALE_FARSI;
            } else {
                locale = LOCALE_AUTO;
            }
            return locale;
        }
    }


    public static Locale getSystemLocale() {
        return systemLocale;
    }


    public static void setSystemLocale(Locale locale) {
        systemLocale = locale;
    }


}

activity:

public class LanguageActivity extends BaseActivity implements View.OnClickListener {

    private LangUtils.RCLocale selectedLocale;
    private LangUtils.RCLocale originalLocale;
    private TextView saveOptionTextView;
    private ImageView chineseCheckbox;
    private ImageView englishCheckbox;
    private ImageView farsiCheckbox;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_language);
        setTitle(R.string.language_setting);

        findViewById(R.id.ll_chinese).setOnClickListener(this);
        findViewById(R.id.ll_english).setOnClickListener(this);
        findViewById(R.id.ll_farsi).setOnClickListener(this);
        chineseCheckbox = (ImageView) findViewById(R.id.img_chinese_checkbox);
        englishCheckbox = (ImageView) findViewById(R.id.img_english_checkbox);
        farsiCheckbox = findViewById(R.id.img_farsi_checkbox);
        saveOptionTextView = findViewById(R.id.text_right);
        saveOptionTextView.setVisibility(View.VISIBLE);
        saveOptionTextView.setText(R.string.confirm);
        saveOptionTextView.setOnClickListener(this);

        originalLocale = ConfigurationManager.getInstance().getAppLocale(this);
        if (originalLocale == LangUtils.RCLocale.LOCALE_CHINA) {
            selectLocale(LangUtils.RCLocale.LOCALE_CHINA);
        } else if (originalLocale == LangUtils.RCLocale.LOCALE_US) {
            selectLocale(LangUtils.RCLocale.LOCALE_US);
        } else if (originalLocale == LangUtils.RCLocale.LOCALE_FARSI) {
            selectLocale(LangUtils.RCLocale.LOCALE_FARSI);
        }
        setSaveOptionTextViewClickable(false);

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.ll_chinese:
                selectLocale(LangUtils.RCLocale.LOCALE_CHINA);
                break;
            case R.id.ll_english:
                selectLocale(LangUtils.RCLocale.LOCALE_US);
                break;
            case R.id.ll_farsi:
                selectLocale(LangUtils.RCLocale.LOCALE_FARSI);
                break;
            case R.id.text_right:
                if (LangUtils.RCLocale.LOCALE_CHINA == selectedLocale) {
                    ConfigurationManager.getInstance().switchLocale(LangUtils.RCLocale.LOCALE_CHINA, this);
                } else if (LangUtils.RCLocale.LOCALE_US == selectedLocale) {
                    ConfigurationManager.getInstance().switchLocale(LangUtils.RCLocale.LOCALE_US, this);
                } else if (LangUtils.RCLocale.LOCALE_FARSI == selectedLocale) {
                    ConfigurationManager.getInstance().switchLocale(LangUtils.RCLocale.LOCALE_FARSI, this);
                }
                backToSettingActivity();
                break;
        }
    }


    private void selectLocale(LangUtils.RCLocale locale) {
        if (locale == LangUtils.RCLocale.LOCALE_CHINA) {
            farsiCheckbox.setImageDrawable(getResources().getDrawable(R.drawable.seal_ic_checkbox_full_gray));
            englishCheckbox.setImageDrawable(getResources().getDrawable(R.drawable.seal_ic_checkbox_full_gray));
            chineseCheckbox.setImageDrawable(getResources().getDrawable(R.drawable.rc_ic_checkbox_full));
            selectedLocale = LangUtils.RCLocale.LOCALE_CHINA;
        } else if (locale == LangUtils.RCLocale.LOCALE_US) {
            chineseCheckbox.setImageDrawable(getResources().getDrawable(R.drawable.seal_ic_checkbox_full_gray));
            farsiCheckbox.setImageDrawable(getResources().getDrawable(R.drawable.seal_ic_checkbox_full_gray));
            englishCheckbox.setImageDrawable(getResources().getDrawable(R.drawable.rc_ic_checkbox_full));
            selectedLocale = LangUtils.RCLocale.LOCALE_US;
        } else if (locale == LangUtils.RCLocale.LOCALE_FARSI) {
            chineseCheckbox.setImageDrawable(getResources().getDrawable(R.drawable.seal_ic_checkbox_full_gray));
            englishCheckbox.setImageDrawable(getResources().getDrawable(R.drawable.seal_ic_checkbox_full_gray));
            farsiCheckbox.setImageDrawable(getResources().getDrawable(R.drawable.rc_ic_checkbox_full));
            selectedLocale = LangUtils.RCLocale.LOCALE_FARSI;
        }
        if (selectedLocale == originalLocale) {
            setSaveOptionTextViewClickable(false);
        } else {
            setSaveOptionTextViewClickable(true);
        }
    }


    private void backToSettingActivity() {
        Intent mainActivity = new Intent(this, MainActivity.class);
        mainActivity.putExtra(MainActivity.INITIAL_TAB_INDEX, MainActivity.TAB_ME_INDEX);

        Intent settingActivity = new Intent(this, AccountSettingActivity.class);

        TaskStackBuilder taskStackBuilder = TaskStackBuilder.create(this);
        taskStackBuilder.addNextIntent(mainActivity);
        taskStackBuilder.addNextIntent(settingActivity);
        taskStackBuilder.startActivities();
        overridePendingTransition(0, 0);
    }


    private void setSaveOptionTextViewClickable(boolean clickable) {
        if (clickable) {
            saveOptionTextView.setClickable(true);
            saveOptionTextView.setTextColor(getResources().getColor(R.color.white));
        } else {
            saveOptionTextView.setClickable(false);
            saveOptionTextView.setTextColor(getResources().getColor(R.color.group_list_gray));
        }
    }
}

以上就是全部的小语种自定义的实现方式和代码,欢迎评论交流

参考资料

Android国际化之小语种自定义Farsi

今天的文章android 国际化切换语言_android studio切换中文[通俗易懂]分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/89460.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注