Cicero
08/15/2021, 11:07 AMCicero
08/15/2021, 11:17 AMval language = Languages.DEFAULT
fun String.localize() =
when (language) {
Languages.ENGLISH -> EnglishStrings()
}
Would be how I would like to fetch my translation where "language" will be user defined setting that will use the systems default.
The supported languages will be an enum this being helpful because the the "when" in the localize parameter will remind you to implement new branches as you grown your supported languages.
enum class Languages {
DEFAULT,
ENGLISH
}
And now I'm, working on finding the best way to organizer this strings.
I really wanted to leverage this implementation to have distributed string files per context, walking away from monolitical approaches because they lose maintenance with time, force you into poor and long names.
I'm listening to everything, mainly what will not work 🙂Adam Powell
08/15/2021, 2:05 PMAdam Powell
08/15/2021, 2:06 PMAdam Powell
08/15/2021, 2:07 PMAdam Powell
08/15/2021, 2:20 PMInt
makes a lousy key. "Type safety" for R constants is provided today by Android Lint alone and it's not as complete as a real type checker. A new solution would ideally use something that participates in the language's type system. However, the performance profile of Int
here is incredibly good. Constants get inlined by the compiler and prevent a lot of overhead. A new solution must not regress the performance profile of working with localized strings either.Adam Powell
08/15/2021, 2:21 PMAdam Powell
08/15/2021, 2:25 PMContext
to load strings, full stop. That makes String.localize()
into something more like String.localize(Context)
at a minimum, which starts getting more cumbersome. Context receivers is also something we're watching for the ergonomics here; Compose doesn't need it since it has access to context from the composition in the form of CompositionLocals. I'd be very wary of adding something that is incredibly easy to load from @Composable
functions but very hard to load outside, as it starts to encourage some really twisted and confusing data flow when folks aren't sure how to get from something like a ViewModel to some data they need. You really really need an Activity
context for this and not the application context, since a lot of developers cobble together some custom locale picking systems within their apps.Adam Powell
08/15/2021, 2:31 PMString
constant with a trailing extension call. It's attractive but problematic in what it implies, since the key needs to be repeated at both point of use and in the table of alternatives. That sort of arrangement is prone to going out of sync when a well-meaning developer makes a change to the inline constant in the source code and now the key is different. Now you need another system to prevent or resolve that. Or you use something closer to the explicit indirection of the R.string.confirm_new_account
style. I think we'd need to see something quite impressive to override the simple advantages of explicit keys like thatAdam Powell
08/15/2021, 2:33 PMAdriel Café
08/16/2021, 5:14 AMCicero
08/16/2021, 9:30 AMAdam Powell
08/16/2021, 2:22 PMAdam Powell
08/16/2021, 2:25 PMCicero
08/18/2021, 11:09 AMCicero
08/18/2021, 11:13 AMAdriel Café
08/18/2021, 12:13 PMinterface Strings {
val featureA: FeatureAStrings
val featureB: FeatureBStrings
}
strings.featureA.someText
Cicero
08/18/2021, 12:47 PMCicero
08/18/2021, 12:52 PMCicero
08/31/2021, 7:46 PMenum class Languages {
English,
Portuguese,
Spanish;
}
val systemLanguage = Languages.English.name
interface SupportedLanguages {
val English: String
val Portuguese: String
val Spanish: String
fun getLocalizedString() = when (systemLanguage) {
this.English.javaClass.name -> English
this.Portuguese.javaClass.name -> Portuguese
this.Spanish.javaClass.name -> Spanish
else -> "Unsoported language"
}
}
sealed class LoginStrings {
class Login(
override val English: String = "Login",
override val Portuguese: String = "Logar",
override val Spanish: String = "Logar"
) : SupportedLanguages
class LoginButtonLabel(): SupportedLanguages {
override val English: String
get() = TODO("Not yet implemented")
override val Portuguese: String
get() = TODO("Not yet implemented")
override val Spanish: String
get() = TODO("Not yet implemented")
}
}
LoginStrings.Login().getLocalizedString()
It's far from practical but it does what I'm interested. Any tips on any approaches Google took on the matter?