从 Android 13 的 locale-config 中获取语言环境列表

8
为了确保您的应用语言可以在运行Android 13或更高版本的设备上进行配置,我们需要创建一个名为locales_config的XML文件,并使用android:localeConfig属性将其添加到我们的应用程序清单中(请参见此处)。
例如,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
1
@CommonsWare 的确是相当底层的...这没关系(它可以工作),但我希望新的 Android 13 地区设置系统能够提供一个专门的方法来查询此信息,以便我们可以实现自己的应用内语言环境选择器,以反映 Android 13 设备上可用的内容(但早期设备上不可用)。 - drmrbrewer
我本希望新的Android 13区域设置系统能够提供一个专门的查询此信息的方法——我不能排除这种可能性。我不记得有这个选项,但是我没有花太多时间研究Android 13的这个特定方面。 - CommonsWare
1个回答

4
这是我用于此目的的Kotlin实用类: LanguageUtil

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 或更高版本


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接