I have a code for changing the language of an APP. When I'm using this code, the language does change but not fully. Some parts of the page I'm in is still having the old language. For e.g., if I'm using English, Portugese and Spanish and when I change from English to Spanish, some parts are of the page are not changing. I have only two activities and rest of the them are fragments. And below is the code I'm using for the app to switch languages.
But when I go out of the page and come back again, the whole page is translated.
fun updateLocale(context: Context, language: String) {
val locale = when (language) {
"Portuguese" -> Locale("pt")
"Spanish" -> Locale("es")
else -> Locale("en")
}
Locale.setDefault(locale)
val config = Configuration()
config.setLocale(locale)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.createConfigurationContext(config)
} else {
@Suppress("DEPRECATION")
context.resources.updateConfiguration(config, context.resources.displayMetrics)
}
}
How do make this function workable? Is there any additional code that has to be added for this to work?
This is how I'm using the code in my activity
Utils.updateLocale(this, App.instance.language)
I tried detaching and attaching the fragment. Recreated activities and still did not work.
I have a code for changing the language of an APP. When I'm using this code, the language does change but not fully. Some parts of the page I'm in is still having the old language. For e.g., if I'm using English, Portugese and Spanish and when I change from English to Spanish, some parts are of the page are not changing. I have only two activities and rest of the them are fragments. And below is the code I'm using for the app to switch languages.
But when I go out of the page and come back again, the whole page is translated.
fun updateLocale(context: Context, language: String) {
val locale = when (language) {
"Portuguese" -> Locale("pt")
"Spanish" -> Locale("es")
else -> Locale("en")
}
Locale.setDefault(locale)
val config = Configuration()
config.setLocale(locale)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.createConfigurationContext(config)
} else {
@Suppress("DEPRECATION")
context.resources.updateConfiguration(config, context.resources.displayMetrics)
}
}
How do make this function workable? Is there any additional code that has to be added for this to work?
This is how I'm using the code in my activity
Utils.updateLocale(this, App.instance.language)
I tried detaching and attaching the fragment. Recreated activities and still did not work.
Share Improve this question asked Feb 3 at 8:55 Abhijith WarrierAbhijith Warrier 157 bronze badges2 Answers
Reset to default 0When you change the language at runtime, some parts of your UI may continue to show old strings because they were composed (or “inflated”) with the previous configuration. In Jetpack Compose (or even in traditional fragments), the UI won’t automatically update if only the locale is changed in the resources. Instead, you have to “force” a recomposition (or even a full recreation) of your composables so that they pick up the new language from resources.
If you're using compose for your UI, you can save the state that tracks the current language and use a key to force a recomposition when it changes, as so:
@Composable fun MainScreen(currentLanguage: String) { key(currentLanguage) { Column(modifier = Modifier.fillMaxSize()) { Text(text = stringResource(id = R.string.hello)) } } }
Another Compose-friendly approach is to provide the current configuration (or locale) via a CompositionLocal.
// saving the state in your fragment/activity private var currentLocale by mutableStateOf(Locale.getDefault()) // setting the composition local provider setContent { CompositionLocalProvider(LocalAppLocale provides currentLocale) { MainScreen() } } val LocalAppLocale = compositionLocalOf { Locale.getDefault() } @Composable fun MainScreen() { // if the configuration changes, the UI will recompose. val locale = LocalAppLocale.current Column { Text(text = stringResource(id = R.string.hello)) } }
Another approach — more common with traditional Android Views is to recreate the activity when the language changes.
You can check out official Android guide: https://developer.android/guide/topics/resources/app-languages#androidx-impl. It works in my case.
val appLocale: LocaleListCompat = LocaleListCompat.forLanguageTags("xx-YY")
// Call this on the main thread as it may require Activity.restart()
AppCompatDelegate.setApplicationLocales(appLocale)
Also, to get your app prefered language that the user choosen, use AppCompatDelegate.getApplicationLocales()
.
If your android version is below 13, declare a compatible service in your Manifest
<application
...
<service
android:name="androidx.appcompat.app.AppLocalesMetadataHolderService"
android:enabled="false"
android:exported="false">
<meta-data
android:name="autoStoreLocales"
android:value="true" />
</service>
...
</application>