slang
slang copied to clipboard
Unsure how to use slang with riverpod + locale preference
For my app the Locale comes out of a riverpod provider (ref.watch(settingsControllerProvider.select((s) => s.appLocale())
) and I don't know how to connect this to the slang interface.
For the intl
module, you just make your top-level widget a ConsumerWidget
, it uses ref.watch as above, then passes that locale to the MaterialApp
locale argument. Then whenever the locale is changed, the entire widget tree is rebuilt with the new language.
With slang
, when if I update the locale, the widget tree is not rebuilt, and stays in English.
I am not sure what I am doing wrong here. My widget tree is main() -> runApp(TranslationProvider(child: MyApp())) where MyApp calls appLocale = ref.watch(...)
and returns MaterialApp(locale: appLocale). Debug print shows the MaterialApp
is being created with a new locale, but nothing is updated.
If I manually call LocaleSettings.setLocale(
in the build method of MyApp, I get the error FlutterError (setState() or markNeedsBuild() called during build. This TranslationProvider widget cannot be marked as needing to build because the framework is already in the process of building widgets. ...
.
I got it working by following https://github.com/Tienisto/slang/blob/master/slang/documentation/dependency_injection.md
It works fine.
I prefer i18n because i18n allows you to refresh the top-level widget, then get translations via AppLocalizations.of(context)
from anywhere. The slang solution requires riverpod to be used everywhere, which is not always convenient.
I don't understand the myEnResolver
part, so I skipped that.
Hi,
yep, riverpod
is the injection solution in your case. Your current solution is quite clean because now the translations are also depending on some riverpod provider.
There are also some other solutions which are more "dirty" but more convenient:
// in your top-level build method
ref.listen<int>(localeProvider, (prev, curr) {
LocaleSettings.setLocaleRaw(curr);
});
// A: call the static instance directly without provider (do not wrap your app with TranslationProvider)
String a = t.myString;
// B: or access the provider (TranslationProvider is needed here)
final t = Translations.of(context);
String a = t.myString;
myEnResolver
is the English plural resolver. The default plural handling will be used if you leave it out :)
Closed due to inactivity