Reputation: 12661
I'm trying to use localisation so that it is available from within my own Flutter plugin. To do this, I'm using an abstract base class called CoreLocalisation
, which is implemented by my concrete AppLocalisation
class. Then I'm using
List<SingleChildCloneableWidget> uiConsumableProviders = <SingleChildCloneableWidget>[
...
Provider<CoreLocalisation>(
create: (context) => AppLocalisation.of(context)
)
];
I'm calling the MultiProvider
from a ContentPage
:
@override Widget build(BuildContext context) {
//final localisation = AppLocalisation.of(context);
return MultiProvider(
providers: uiConsumableProviders,
child: ...
);
}
What is confusing me is that the commented out call to AppLocalisation.of(context)
works perfectly, but the invocation within the MultiProvider
throws the following exception:
FlutterError (inheritFromWidgetOfExactType(_LocalizationsScope) or inheritFromElement() was called before BuilderStateDelegate.initDelegate() completed.
In my understanding, the child context should have access to all of the elements available to the parent context. Am I missing something fundamental?
Upvotes: 1
Views: 163
Reputation: 12661
I didn't solve the problem explicitly, but I set up a workaround. First of all, I created a provider whose job was simply to convert a context into a concrete instance of CoreLocalisation
. It used this class in the plugin:
class CoreLocalisationProvider {
final CoreLocalisation Function(BuildContext) of;
CoreLocalisationProvider(this.of);
}
Then the provider in the consuming app looked like this:
Provider<CoreLocalisationProvider>.value(value: CoreLocalisationProvider((context) => AppLocalisation.of(context)))
and I can add the following syntactic sugar to CoreLocalisation
:
static CoreLocalisation of(BuildContext context) => Provider.of<CoreLocalisationProvider>(context).of(context);
This admittedly looks clumsy, but it permits me to use the familiar syntax CoreLocalisation.of(context)
throughout the codebase, as if CoreLocalisation
were a common-or-garden concrete localisation class.
Upvotes: 0
Reputation: 9903
You can't call Localizations.of
(which calls inheritFromWidgetOfExactType
) synchronously inside of initState
, because the widget tree is still being built in that moment and you can't access inherited widget. You can call it using asynchronous callback:
Timer.run(() {
AppLocalizations.of(this.context);
});
or from post-frame callback:
WidgetsBinding.instance.addPostFrameCallback((_) {
AppLocalizations.of(this.context);
});
Upvotes: 1