title: How to implement Flutter Localization with Provider?
body: <p>I wanted to make my application to work in 2 different language.
  I guess problem is that I cannot handle <em>Cosumer</em> in multiprovider ,could it be?</p>
  <p>I am using flutter_localization package alongside with flutter provider package;</p>
  <p>Here is my code:</p>
  <pre><code>void main() async {
    WidgetsFlutterBinding.ensureInitialized();
    AppLanguage appLanguage = AppLanguage();
    await appLanguage.fetchLocale();
    SharedPreferences.getInstance().then((prefs) {
      var darkModeOn = prefs.getBool('darkMode') ?? true;
      runApp(
        ChangeNotifierProvider&lt;ThemeManager&gt;(
          builder: (_) =&gt; ThemeManager(lightTheme),
          child: MyApp(appLanguage: appLanguage),
        ),
      );
    });
  }
  </code></pre>
  <p>Class My App</p>
  <pre><code>class MyApp extends StatelessWidget {
    final AppLanguage appLanguage;
  
    MyApp({this.appLanguage});
    @override
    Widget build(BuildContext context) {
      final themeNotifier = Provider.of&lt;ThemeManager&gt;(context);
      return MultiProvider(
        providers: [
          ChangeNotifierProvider.value(value: ApiService()),
          ChangeNotifierProxyProvider&lt;ApiService, StudentData&gt;(
            builder: (ctx, auth, _) =&gt; StudentData(auth.token, auth.school),
          )
        ],
        child: Consumer&lt;ApiService&gt;(
          builder: (ctx, auth, _) =&gt; ChangeNotifierProvider&lt;AppLanguage&gt;(
            builder: (_) =&gt; appLanguage,
            child: Consumer&lt;AppLanguage&gt;(
              builder: (context, model, child) =&gt; MaterialApp(
                locale: appLanguage.appLocal,
                supportedLocales: [Locale('ru', 'RU'), Locale('uz', 'UZ')],
                localizationsDelegates: [
                  AppLocalization.delegate,
                  GlobalMaterialLocalizations.delegate,
                  GlobalWidgetsLocalizations.delegate,
                ],
                debugShowCheckedModeBanner: false,
                title: &quot;Socratus |Mobile&quot;,
                theme: themeNotifier.getTheme(),
                home: auth.isAuth
                    ? MainScreen()
                    : FutureBuilder(
                        future: auth.tryAutoLogin(),
                        builder: (ctx, authResultSnapshot) =&gt; LoginScreen()),
                routes: {
                  MainScreen.routeName: (ctx) =&gt; MainScreen(),
                  ProfilePage.routeName: (ctx) =&gt; ProfilePage(),
                  SettingsPage.routeName: (ctx) =&gt; SettingsPage(
                        appLanguage: appLanguage,
                      ),
                  ChangePassword.routeName: (ctx) =&gt; ChangePassword(),
                  HomeworkScreen.routeName: (ctx) =&gt; HomeworkScreen(),
                  HWDetails.routeName: (ctx) =&gt; HWDetails(),
                  NewsPage.routeName: (ctx) =&gt; NewsPage(),
                  QuestionAndAnswers.routeName: (ctx) =&gt; QuestionAndAnswers(),
                  MyDownloads.routeName: (ctx) =&gt; MyDownloads(),
                },
              ),
            ),
          ),
        ),
      );
    }
  }
  </code></pre>
  <p>Here how I tried to implement</p>
  <pre><code>class AppLocalization {
    final Locale locale;
  
    AppLocalization(this.locale);
  
    static AppLocalization of(BuildContext context) {
      return Localizations.of&lt;AppLocalization&gt;(context, AppLocalization);
    }
  
    static const LocalizationsDelegate&lt;AppLocalization&gt; delegate =
        _AppLocalizationDelegate();
  
    Map&lt;String, String&gt; _localizedStrings;
  
    Future&lt;bool&gt; load() async {
      String jsonString = await rootBundle
          .loadString('assets/translations/${locale.languageCode}.json');
      Map&lt;String, dynamic&gt; jsonMap = json.decode(jsonString);
  
      _localizedStrings = jsonMap.map((key, value) {
        return MapEntry(key, value.toString());
      });
  
      return true;
    }
  
    String translate(String key) {
      return _localizedStrings[key];
    }
  }
  
  class _AppLocalizationDelegate extends LocalizationsDelegate&lt;AppLocalization&gt; {
    // This delegate instance will never change (it doesn't even have fields!)
    // It can provide a constant constructor.
    const _AppLocalizationDelegate();
  
    @override
    bool isSupported(Locale locale) {
      // Include all of your supported language codes here
      return ['ru', 'uz'].contains(locale.languageCode);
    }
  
    @override
    Future&lt;AppLocalization&gt; load(Locale locale) async {
      AppLocalization localizations = new AppLocalization(locale);
      await localizations.load();
      return localizations;
    }
  
    @override
    bool shouldReload(_AppLocalizationDelegate old) =&gt; false;
  }
  </code></pre>
  <p>And my provider :</p>
  <pre><code>class AppLanguage extends ChangeNotifier {
    Locale _appLocale = Locale('ru');
  
    Locale get appLocal =&gt; _appLocale ?? Locale(&quot;ru&quot;);
    fetchLocale() async {
      var prefs = await SharedPreferences.getInstance();
      if (prefs.getString('language_code') == null) {
        _appLocale = Locale('ru');
        return Null;
      }
      _appLocale = Locale(prefs.getString('language_code'));
      return Null;
    }
  
    void changeLanguage(Locale type) async {
      var prefs = await SharedPreferences.getInstance();
      if (_appLocale == type) {
        return;
      }
      if (type == Locale(&quot;uz&quot;)) {
        _appLocale = Locale(&quot;uz&quot;);
        await prefs.setString('language_code', 'uz');
        await prefs.setString('countryCode', 'UZ');
      } else {
        _appLocale = Locale(&quot;ru&quot;);
        await prefs.setString('language_code', 'ru');
        await prefs.setString('countryCode', 'RU');
      }
      notifyListeners();
    }
  }
  </code></pre>
  <p>If this is not a correct way , how can I implement this feature ?</p>