skip to Main Content

I folowed this video to implement localization in my app :- https://youtu.be/Zw4KoorVxgg

Everything works fine but when the app is relaunched the language gets set to default. How can I persiste the data.

[Note:- I am already using shared preference to persist some other data in my app, but I have no clue about persisting selected Locale]

This class below is called to set the locale:

class LocaleProvider extends ChangeNotifier {
  Locale? _locale;

  Locale? get locale => _locale;

  void setLocale(Locale locale) {
    if (!L10n.all.contains(locale)) return;
    _locale = locale;
    notifyListeners();
  }

  void clearLocale() {
    _locale = null;
    notifyListeners();
  }
}

And this is the screen where I set the language:

  class SelectLanguage extends StatefulWidget {
  const SelectLanguage({Key? key}) : super(key: key);

  @override
  _SelectLanguageState createState() => _SelectLanguageState();
}

class _SelectLanguageState extends State<SelectLanguage> {
  void setLocale(String selectedLocale) {
    final provider = Provider.of<LocaleProvider>(context, listen: false);
    provider.setLocale(
      Locale(selectedLocale),
    );
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        backgroundColor: Colors.black,
        body: Padding(
          padding:
          EdgeInsets.all(MediaQuery.of(context).size.width / 41.1),
          child: GridView(
            gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
              crossAxisCount: 2,
              childAspectRatio: 2.75,
              crossAxisSpacing: MediaQuery.of(context).size.width / 41.1,
              mainAxisSpacing: MediaQuery.of(context).size.width / 41.1,
            ),
            children: [
              LanguageTile(
                tileTitle: 'English',
                titleOnTap: () => setLocale('en'),
              ),
              LanguageTile(
                tileTitle: 'हिन्दी',
                titleOnTap: () => setLocale('hi'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

2

Answers


  1. using shared preference

    static Future<Locale> setLocale(String langCode) async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    await prefs.setString(languageCode, langCode);
    return locale(langCode);
    }
    
    static Locale locale(String languageCode) {
    Locale _temp;
    if (languageCode == 'hi') {
      _temp = Locale('hi');
    }
    
    else {
      _temp = Locale('en');
    }
    return _temp;
    }
    
    static Future<Locale> getLocale() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    String code = prefs.getString(languageCode);
    
    print('language code:$code');
    
    return locale(code);
    }
    
    Login or Signup to reply.
  2. create a class

        import 'dart:ui';
    
    import 'package:shared_preferences/shared_preferences.dart';
    
    const String LAGUAGE_CODE = 'languageCode';
    
    //languages code
    const String ENGLISH = 'en';
    const String FRENCH = 'fr';
    const String ARABIC = 'ar';
    const String KINYARWANDA = 'rw';
    const String SWAHILLI ="sw";
    
    Future<Locale> storeLocale(String languageCode) async {
      SharedPreferences _prefs = await SharedPreferences.getInstance();
      await _prefs.setString(LAGUAGE_CODE, languageCode);
      return _locale(languageCode);
    }
    
    Future<Locale> getLocale() async {
      SharedPreferences _prefs = await SharedPreferences.getInstance();
      String languageCode = _prefs.getString(LAGUAGE_CODE) ?? ENGLISH;
      return _locale(languageCode);
    }
    
    Locale _locale(String languageCode) {
      switch (languageCode) {
        case ENGLISH:
          return const Locale(ENGLISH, '');
        case FRENCH:
          return const Locale(FRENCH, "");
        case ARABIC:
          return const Locale(ARABIC, "");
        case KINYARWANDA:
          return const Locale(KINYARWANDA, "");
        case SWAHILLI:
          return const Locale(SWAHILLI, "");
        default:
          return const Locale(ENGLISH, '');
      }
    }
    

    then in your provider class add

         Future<void> setLocale(Locale locale) async{
        if(!L10n.all.contains(locale)) return;
        _locale =locale;
        storeLocale(locale.languageCode);//add this important
        // storelocal(locale.languageCode);
        notifyListeners();
    
      }
    

    where or widget you are implementing it e.g dropdown

    Widget build(BuildContext context) {
        final provider = Provider.of<LocaleProvider>(context,);
        final locale = provider.locale ?? const Locale('en');
        return DropdownButtonHideUnderline(
            child: DropdownButton(
          value: locale,
          icon: const Icon(Icons.language,color:Colors.white,),
          items: L10n.all.map((locale) {
            final flag = L10n.getFlag(locale.languageCode);
            return DropdownMenuItem(
              value: locale,
              onTap: ()async {
                //await storeLocale(locale.languageCode);//may uncomment this
                final provider =
                    Provider.of<LocaleProvider>(context,listen: false );
                provider.setLocale(locale);
              },
    

    and in the main.dart change to stateful and override

     @override
      void didChangeDependencies() {
        super.didChangeDependencies();
       getLocale().then(
            (locale) => Provider.of<LocaleProvider>(context,listen: false).setLocale(locale));
      }
    

    hope this helps

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search