3

I'm new to flutter and Dart currently, I'm using flutter 2.03 and trying to build a multi-language app using the easy_localization package (3.0.0). At first, everything was alright when I try to change the app language from the setting page or the first page which is shown one time, the app translates the content and stays on the same page but yesterday the app started reloading when I change the app locale :

onChanged: (newValue) async {
 if (newValue == 'English') {
     await context.setLocale(Locale('en'));
 } else if (newValue == 'Français') {
     await context.setLocale(Locale('fr'));
 } else if (newValue == 'العربية') {
     await context.setLocale(Locale('ar'));
 }
},

All I want is to make the app make hot reload and translate the page and stay on the same screen without reloading the whole app and back to Home Screen.

Main.dart

import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:sg_user_dash/screens/homescreen.dart';
import 'package:sg_user_dash/screens/language.dart';
import 'package:shared_preferences/shared_preferences.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await EasyLocalization.ensureInitialized();
  runApp(EasyLocalization(
      supportedLocales: [Locale('en'), Locale('fr'), Locale('ar')],
      path: 'assets/translations',
      fallbackLocale: Locale('en'),
      child: MyApp()));
}

Future<String> nextdisplay() async {
  SharedPreferences prefs = await SharedPreferences.getInstance();
  bool _seen = (prefs.getBool('seen') ?? false);

  if (_seen) {
    return "Homepage";
  } else {
    await prefs.setBool('seen', true);
    return "walkthrough";
  }
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        debugShowCheckedModeBanner: false,
        title: 'Smart Government',
        theme: ThemeData(),
        localizationsDelegates: context.localizationDelegates,
        supportedLocales: context.supportedLocales,
        locale: context.locale,
        home: FutureBuilder(
            future: nextdisplay(),
            builder: (context, AsyncSnapshot<String> snapshot) {
              if (snapshot.hasData) {
                if (snapshot.data == "walkthrough") {
                  return Language();
                } else if (snapshot.data == "Homepage") {
                  return HomeScreen();
                } else {
                  return Language();
                }
              }
              return Center(
                child: CupertinoActivityIndicator(),
              );
            }));
  }
}

Thank you <3

seif khelifi
  • 45
  • 1
  • 4
  • I didn't mention that yesterday I tried to implement dark mode using provider and notifierlistener and the result was bad so I deleted that. can that affect easy_localizations? – seif khelifi May 02 '21 at 15:26

3 Answers3

1

I have a solution if someone needs to change locale on Android or IOs automatically from device settings.

Since changing the language usually requires changing the app with focus, your app will pause and resume when you return to it.

For this reason I have used the app life cycle as a listener to change the language, giving me good results. (Check the docs for more info about App Lifecycle: Android | IOs).

Next I will show a simple example that could be useful to you.

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await EasyLocalization.ensureInitialized();

  runApp(
    EasyLocalization(
      supportedLocales: const [
        Locale('es'),
        Locale('en'),
        Locale('fr'),
        Locale('pt'),
        Locale('it'),
        Locale('de'),
      ],
      fallbackLocale: const Locale('en'),
      path: 'res/assets/langs',
      useOnlyLangCode: true,
      child: const MyApp(),
    ),
  );
}

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

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {

  @override
  void initState() {
      super.initState();

      WidgetsBinding.instance.addObserver(
      LifecycleEventHandler(
        resumeCallBack: () {
          final locale = context.locale.toString();

          // Get lang code only if not using country code.
          final platformLocale = Platform.localeName.split("_")[0];

          if(platformLocale != locale) {
            // Select device lang or English if not supported.
            final supportedLocale = getSuppLangOrEn(platformLocale);
            context.setLocale(Locale(supportedLocale));
          }
        },
      ),
    );
  }
  
  @override
  Widget build(BuildContext context) {    
    return MaterialApp(
        localizationsDelegates: context.localizationDelegates,
        supportedLocales: context.supportedLocales,
        locale: context.locale,
        title: 'Localized App',
        theme: theme,
        home: const HomeScreen(),
        initialRoute: HomeScreen.routeName,
        routes: routes,
      ),
    );
  }
}

And the LifecycleEventHandler would look like this:

class LifecycleEventHandler extends WidgetsBindingObserver {
  final VoidCallback? resumeCallBack;
  final VoidCallback? suspendingCallBack;

  LifecycleEventHandler({
    this.resumeCallBack,
    this.suspendingCallBack,
  });

  @override
  Future<void> didChangeAppLifecycleState(AppLifecycleState state) async {
    switch (state) {
      case AppLifecycleState.resumed:
        if (resumeCallBack != null) {
          resumeCallBack!();
        }
        break;
      case AppLifecycleState.inactive:
      case AppLifecycleState.paused:
      case AppLifecycleState.detached:
        if (suspendingCallBack != null) {
          suspendingCallBack!();
        }
        break;
    }
  }
}

Credits: LifecycleEventHandler code was taken from here.

AlejandroQS
  • 358
  • 4
  • 8
0

easy_localization save the language when its change on runtime you don't need to save it again. I have a video on how to use easy_localization I think it can be a help

https://www.youtube.com/watch?v=LS8KFYsR244

  • man it was working fine and I did the same work that u do in your video, just a couple of days it started reloading when I change the language id don,t know why – seif khelifi May 04 '21 at 22:07
0

so sample add setState((){}); thats work for me, But I dont know why :)

onChanged: (newValue) async {
 if (newValue == 'English') {
     await context.setLocale(Locale('en'));
     
 } else if (newValue == 'Français') {
     await context.setLocale(Locale('fr'));
 } else if (newValue == 'العربية') {
     await context.setLocale(Locale('ar'));
 }
 setState((){});
},
Rahman Rezaee
  • 1,943
  • 16
  • 24