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

Android国际化之小语种自定义Farsi老规矩 先上效果图 图中分别展示了由应用内由中文切换到英文再到波斯语的展示 本篇博客介绍的两个点 小语种的自定义 应用内无感知切换语言 一 小语种的自定义 Java Locale 的语言常量基本囊括了主流语言 public static final Locale CANADA null public

大家好,我是讯享网,很高兴认识大家。

老规矩 ,先上效果图

这里写图片描述
讯享网

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

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

一、小语种的自定义

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.

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

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

参考资料

https://blog.csdn.net/chougod/article/details/

小讯
上一篇 2025-01-24 10:43
下一篇 2025-03-14 13:33

相关推荐

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