I am building a multimodule gameapp with Compose and Koin dependency injection. Every module manages its own screens and navigation. The structure is this:
app:
core:
|- common
feature:
|-games:
| |-general:
| |-meaninggame:
| |-completiongame:
|
|-highscores
etc.
There are multiple gamemodes, each implemented as a seperate module. MeaningGame and Completiongame are examples of those. Each gamemodule has to implement an interface so it can be registered in the list of games.
GameApi:
interface GameApi {
fun registerGame(
navGraphBuilder: NavGraphBuilder,
navController: NavHostController,
modifier: Modifier = Modifier
)
fun gameRoute():GameRoutes
fun title(): Int
fun id():Int
}
The gameRoute() returns the route to navigate to the game, the id() the unique id of the game. This id is used to store the score of the game on a server, show a list of highscores (retrieved from the server) etc. And the title() returns the resource-identifier from R.string.title. This resource file is contained in the module.
The problem is this. In the highscore module I want to show the title of the game in the language of the user. So if an American watches the highscores, he sees the title in English, but a German would see the German variant, a Frenchman the French variant and so on.
How can I access the resource from a gamemodule in the highscore module?
I tried to build a function in the gameApi Interface to register the string in a local database (which would be in the core: module) but I am unsuccesfull as I do not have access to the Context in the gameApi implementation, so stringResource does not work and context.resources.getString(..) also does not work.
Does anyone has an idea?
So usually i would define the string resource with other localization
you can see more in this documentation String Localization.Then i would modify the title with parameter Locale, Then if you can't access the Context for some reason, give the context responsible to other's using dependency injection usually i use koin but you can use other thing.
for example
interface GameApi {
fun registerGame(
navGraphBuilder: NavGraphBuilder,
navController: NavHostController,
modifier: Modifier = Modifier
)
fun gameRoute():GameRoutes
//return string, so we don't need to care what id need to be used
fun title(locale: Locale): String
fun id():Int
}
//the impl
class HighscoreGameApi(context: Context) : GameApi{
private val applicationContext = context.applicationContext
//other code
override fun title(locale: Locale): String {
val config = applicationContext.resources.configuration
config.setLocale(locale)
val localizedResource = applicationContext.createConfigurationContext(config).resources
return localizedResource.getString(R.string.the_title_text)
}
}
//injection
//im using koin, this is just registering the module
//not the full implementation of koin injection, see more
//https://insert-koin.io/docs/reference/koin-android
val gameModules = modules {
single {
HighscoreGameApi(androidContext())
}
}
Hope this helpful