使用每个应用的语言首选项对应用进行更改时出现问题

Problems making changes to the app with per-app language preferences

提问人:Jéluchu 提问时间:7/7/2023 更新时间:7/7/2023 访问量:108

问:

我目前正在实现我在另一个应用程序中拥有并且工作正常的代码,以制作语言选择器。我发现的问题是,当我按照相同的步骤操作时,它在我的另一个应用程序中可以工作,但在新应用程序中,它并没有完成更改语言。

访问可用语言列表时,您按其中一种语言,应用程序会冻结,它不会返回,您也无法选择其他选项。如果您退出并重新进入应用程序,您会看到语言已更改,但如果您再次尝试更改语言,它会再次冻结。

通过logcat,我看到以下消息:

  • 存储应用程序区域设置:app-locales:en成功保存。
  • 安排重新启动活动:com.jeluchu.test.MainActivity

所以我明白更改已正确完成,但屏幕没有刷新。这是我用来实现此功能的代码,以防有人知道错误可能是什么

清单

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    <application
        ...
        android:localeConfig="@xml/locales_config"
        ...
        tools:targetApi="tiramisu">

        ...

        <service
            android:name="androidx.appcompat.app.AppLocalesMetadataHolderService"
            android:enabled="false"
            android:exported="false">
            <meta-data
                android:name="autoStoreLocales"
                android:value="true" />
        </service>
    </application>
</manifest>

locales_config

<locale-config xmlns:android="http://schemas.android.com/apk/res/android">
    <locale android:name="en"/>
    <locale android:name="es"/>
</locale-config>

语言设置.kt

private fun getLanguageNumberByCode(languageCode: String): Int =
    languageMap.entries.find { it.value == languageCode }?.key ?: 0

fun getLanguageNumber(): Int {
    return if (Build.VERSION.SDK_INT >= 33)
        getLanguageNumberByCode(
            LocaleListCompat.getAdjustedDefault()[0]?.toLanguageTag().toString()
        )
    else getLanguage
}

@Composable
fun getLanguageDesc(language: Int = getLanguageNumber()): String = stringResource(
    when (language) {
        ENGLISH -> R.string.la_en_US
        SPANISH -> R.string.la_es
        else -> R.string.follow_system
    }
)

private const val ENGLISH = 1
private const val SPANISH = 2

val languageMap: Map<Int, String> = mapOf(
    ENGLISH to "en",
    SPANISH to "es"
)

LanguageView.kt(在 Compose 中)

 val language = rememberMutableStateOf(getLanguageNumber())

 Scaffold {
  LazyColumn {

    item {

                PreferenceSingleChoiceItem(
                    modifier = Modifier.background(milky),
                    text = R.string.follow_system.toStringRes(),
                    selected = language.value == 0,
                    contentPadding = PaddingValues(horizontal = 12.dp, vertical = 18.dp)
                ) { onLanguageClick(language, 0) }
    }

            languageMap.forEach { languageData ->
                item {
                    PreferenceSingleChoiceItem(
                        modifier = Modifier.background(milky),
                        text = getLanguageDesc(languageData.key),
                        selected = language.value == languageData.key,
                        contentPadding = PaddingValues(horizontal = 12.dp, vertical = 18.dp)
                    ) { onLanguageClick(language, languageData.key) }
                }
            }
   }

 }


onLanguageClick 函数为:

  languageMap.getOrElse(PreferencesService.getLanguage) { "" }.setLanguage()
  selected.value = id

.setLanguage() 为:

fun String.setLanguage() = AppCompatDelegate.setApplicationLocales(
    if (isEmpty()) LocaleListCompat.getEmptyLocaleList()
    else LocaleListCompat.forLanguageTags(this)
)
Android Kotlin android-jetpack-compose 语言环境 android-appcompat

评论

0赞 Jéluchu 7/7/2023
依赖项 androidx.appcompat:appcompat:1.6.0 包含在 gradle 中

答: 暂无答案