Update
In the application class, I am injecting the ChangeLanguageRepository
which sets the app language at each app startup by calling the function changeLanguage
.
class ChangeLanguageRepository @Inject constructor(@ApplicationContext private val context: Context) {
fun changeLanguage(languageLocale: String) {
val locale = Locale(languageLocale)
Locale.setDefault(locale)
val config = Configuration()
config.locale = locale
context.resources.updateConfiguration(config, context.resources.displayMetrics)
}
}
I have developed an app using Jetpack Compose in which there is an option to change the language of the app. Now, when the language is changed, all the string resources that are loaded using stringResource()
are not updating for the current locale even when the activity or app is restarted.
One of the screens inside the app is loading strings using the Context
provided by Dagger Hilt in the Repository as shown below.
class HelplineRepository @Inject constructor(@ApplicationContext private val context: Context) {
fun getHelplines(): List<Helpline> {
val ambulance = Helpline(
Icons.Rounded.Emergency,
context.getString(R.string.helpline_text_ambulance),
context.getString(R.string.helpline_text_ambulance_number)
)
val fireStation = Helpline(
Icons.Rounded.LocalFireDepartment,
context.getString(R.string.helpline_text_fire_station),
context.getString(R.string.helpline_text_fire_station_number)
)
return listOf(ambulance, fireStation, policeControlRoom, womenHelpLine)
}
}
This screen properly shows the localized strings when the language is changed but the rest of the screens where I use the stringResource()
inside a composable to load the strings don't update for the current locale.
Note: I have already tried restarting both the activity and the app and have also made sure that the locale is being changed when the user changes the language.
I also found a thread on the issue tracker mentioning a similar problem but couldn't find the solution.
Any help will be appreciated.
Updated answer
Composable code
@Composable
fun LocalizedGreeting() {
val context = LocalContext.current
Box(
contentAlignment = Alignment.Center,
modifier = Modifier
.fillMaxSize(),
) {
Column {
Button(
onClick = {
changeLanguage(
context = context,
language = "it",
)
},
) {
Text("Italian")
}
Button(
onClick = {
changeLanguage(
context = context,
language = "en",
)
},
) {
Text("English")
}
Text(
stringResource(
id = R.string.localized_greeting,
)
)
}
}
}
fun changeLanguage(
context: Context,
language: String,
) {
val locale = Locale(language)
Locale.setDefault(locale)
val config = Configuration()
config.locale = locale
context.resources.updateConfiguration(config, context.resources.displayMetrics)
context.startActivity(Intent.makeRestartActivityTask((context as Activity).intent?.component))
}
Video
The resources remain the same as the old answer given below.
After the language is changed, the activity has to be restarted to get the updated strings. If there are multiple activities in the back stack, all of them have to be restarted.
(For using the localized strings without changing the locale programmatically)
To use localized string resources,
Composable code
@Composable
fun LocalizedGreeting() {
Box(
contentAlignment = Alignment.Center,
modifier = Modifier
.fillMaxSize(),
) {
Text(
stringResource(
id = R.string.localized_greeting,
)
)
}
}
Default strings
res/values/strings.xml
<resources>
<string name="localized_greeting">Hello!</string>
</resources>
Italian strings
res/values-it/strings.xml
<resources>
<string name="localized_greeting">Ciao!</string>
</resources>
jetpackComposeVersion = "1.2.0-beta02"
Using localized strings was straightforward.
Probably you were missing something.
Provide the code you are using for further debugging if required.