Shourya Shikhar
Shourya Shikhar

Reputation: 1524

Flutter GetX updateLocale not refreshing app

I've created a global language controller, that's responsible for updating the locale across the whole app. However, I'm noticing that a freshly visited page after changing the language is being rendered in the newly changed language. But any previously visited pages render the old language until the full app restart.

The language controller:

class LanguageController extends GetxController {
  final RxString currentLangCode = 'en_IN'.obs;
  final RxString currentLang = 'English'.obs;

  static const String LANG_CODE_KEY = 'lang_code';
  static const String LANG_NAME_KEY = 'lang_name';

  final prefs = Get.find<HiveStorage>();

  final Map<String, String> languageOptions = {
    EN_IN: 'English',
    HI_IN: 'हिंदी',
    ...
  };

  @override
  void onInit() {
    super.onInit();
    loadSavedLanguage();
  }

  Future<void> loadSavedLanguage() async {
    final savedLangCode = prefs.read(key: LANG_CODE_KEY);
    final savedLangName = prefs.read(key: LANG_NAME_KEY);

    if (savedLangCode == null || savedLangName == null) {
      return;
    }

    await changeLanguage(savedLangCode, savedLangName);
  }

  Future<void> changeLanguage(String langCode, String langName) async {
    final locale = Locale(langCode.split('_')[0], langCode.split('_')[1]);
    await Get.updateLocale(locale);

    currentLangCode.value = langCode;
    currentLang.value = langName;

    await prefs.write(key: LANG_CODE_KEY, value: langCode);
    await prefs.write(key: LANG_NAME_KEY, value: langName);

    if (Get.context != null) {
      await Get.forceAppUpdate();
    }

    update();
  }
}

this is my main.dart file:

Future<void> main() async {
  WidgetsBinding widgetsBinding = WidgetsFlutterBinding.ensureInitialized();
  // ....
  Get.put<LanguageController>(LanguageController());
  runApp(
    const MyApp(),
  );
}

class MyApp extends GetView<LanguageController> {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return GetBuilder<LanguageController>(
      builder: (LanguageController controller) {
        return GetMaterialApp(
          translations: Languages(),
          translationsKeys: Languages().keys,
          locale: Locale(controller.currentLangCode.value.split('_')[0],
              controller.currentLangCode.value.split('_')[1]),
          fallbackLocale: Get.deviceLocale,
          useInheritedMediaQuery: true,
          debugShowCheckedModeBanner: false,
          navigatorObservers: [
            ...(isProdEnv()
                ? [
                    FirebaseAnalyticsObserver(
                        analytics: FirebaseAnalytics.instance),
                    NavObserverService(),
                  ]
                : [])
          ],
          initialRoute: Routes.login,
          theme: ThemeData(
            fontFamily: 'Poppins',
            visualDensity: VisualDensity.adaptivePlatformDensity,
          ),
          getPages: AppPages.routes,
        );
      },
    );
  }
}

In one of the other screens, I'm finding the language controller and then calling the changeLanguage function. It executes, but still the app language isn't getting changed.

onTap: () async {
  final LanguageController languageController = Get.find<LanguageController>();
  languageController.changeLanguage(langCode, text);
}

Upvotes: 4

Views: 140

Answers (1)

Nnamani Daniel
Nnamani Daniel

Reputation: 81

Get.put(LanguageController()), initializes the controller in the scope of the GetMaterialApp. and Get.find() find the controller in the scope of the GetMaterialApp.

GetBuilder<LanguageController>(
  builder: (LanguageController controller) {
    return GetMaterialApp(...

the GetBuilder is outside the scope of GetMaterialApp;

so You either create a global variable (you can still use Getit package)

class Global{
static final languageController = LanguageController();
}

class MyApp extends GetView<LanguageController> {
const MyApp({super.key});

@override
Widget build(BuildContext context) {
 return GetBuilder<LanguageController>(
  init: Global.languageController,
  builder: (LanguageController controller) {
    return GetMaterialApp(....



onTap: () async {
 Global.languageController.changeLanguage(langCode, text);
}

Upvotes: 1

Related Questions