【问题标题】:Get list of locales from locale-config in Android 13从 Android 13 中的语言环境配置获取语言环境列表
【发布时间】:2022-12-10 02:26:37
【问题描述】:

为确保您的应用程序的语言可在运行 Android 13 或更高版本的设备的系统设置中进行配置,我们需要创建一个 locales_config XML 文件,并使用 android:localeConfig 属性 (see here) 将其添加到我们的应用程序清单中。

例如,locales_config.xml 可能包含:

<?xml version="1.0" encoding="utf-8"?>
<locale-config xmlns:android="http://schemas.android.com/apk/res/android">
   <locale android:name="en"/>
   <locale android:name="en-GB"/>
   <locale android:name="fr"/>
   <locale android:name="ja"/>
   <locale android:name="zh-Hans-MO"/>
   <locale android:name="zh-Hant-MO"/>
</locale-config>

如果我们还想在我们的应用程序设置中提供自定义语言环境选择器,我们如何从locales_config.xml 检索支持的语言环境列表以填充我们的选择器(无需在语言环境选择器代码中复制该列表)?

【问题讨论】:

  • 给定一个 Context,调用 getResources().getXml(R.xml.locales_config) 以获得关于您的 XML 资源内容的 XmlResourceParser
  • @CommonsWare 似乎很低级别......这很好(而且它会起作用)但我希望新的 Android 13 语言环境系统能够提供一种专用方法来查询此信息,以便我们可以实现我们自己的应用内语言环境选择器来镜像 Android 13 设备(但不是更早的设备)上可用的内容?
  • “我希望新的 Android 13 语言环境系统能够提供一种查询这些信息的专用方法”——我不能排除这种可能性。我不记得有这个选项,但我没有花很多时间研究 Android 13 的这个特定方面。

标签: android locale


【解决方案1】:

这是我为此目的使用的 kotlin util 类:

语言实用程序班级


fun Context.getLocaleListFromXml(): LocaleListCompat {
    val tagsList = mutableListOf<CharSequence>()
    try {
        val xpp: XmlPullParser = resources.getXml(R.xml.locales_config)
        while (xpp.eventType != XmlPullParser.END_DOCUMENT) {
            if (xpp.eventType == XmlPullParser.START_TAG) {
                if (xpp.name == "locale") {
                    tagsList.add(xpp.getAttributeValue(0))
                }
            }
            xpp.next()
        }
    } catch (e: XmlPullParserException) {
        e.printStackTrace()
    } catch (e: IOException) {
        e.printStackTrace()
    }

    return LocaleListCompat.forLanguageTags(tagsList.joinToString(","))
}


fun Context.getLangPreferenceDropdownEntries(): Map<String, String> {

    val localeList = getLocaleListFromXml()
    val map = mutableMapOf<String, String>()

    for (a in 0 until localeList.size()) {
        localeList[a].let {
            map.put(it.getDisplayName(it), it.toLanguageTag())
        }
    }
    return map
}


fun setLocale(langTag: String){
  val appLocale: LocaleListCompat = LocaleListCompat.forLanguageTags(langTag)
   AppCompatDelegate.setApplicationLocales(appLocale)
}

用法示例:

 val map = requireContext().getLangPreferenceDropdownEntries()

 findPreference<DropDownPreference>("key_lang")?.apply {
        entries = map.keys.toTypedArray()
        entryValues = map.values.toTypedArray()
        onPreferenceChangeListener =  Preference.OnPreferenceChangeListener { _, newValue ->
              (newValue as String).let{
                     value = it
                     setLocale(it)
              }
              true
           }
     }

需要Appcompat 1.6.0-beta01 or higher

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-06
    相关资源
    最近更新 更多