John Deck
John Deck

Reputation: 899

update font family based on selected language

Using Flutter and Getx .. i want to update the font family based on selected language .. so if i select english language the font family updated to "Poppins" .. if it arabic the font updated to "Cairo" .. i tried this in controller and the font family changed but the theme did not updated

main.dart

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await initialServices();
  LanguageController controller = Get.put(LanguageController());
  runApp(
    GetMaterialApp(
      themeMode: ThemeMode.light,
      theme: AppTheme.lightTheme,
      darkTheme: AppTheme.darkTheme,
      getPages: AppPages.routes,
      initialRoute: AppPages.INITIAL,
      translations: AppTranslation(),
      locale: controller.initLang,

    ),
  );
}

and the app theme class

class AppTheme {
  AppTheme._();

  static ThemeData lightTheme = _buildLightTheme();
  static ThemeData darkTheme = _buildDarkTheme();

// ---------------- LIGHT THEME ---------------- //
  static ThemeData _buildLightTheme() {
    return ThemeData(
      fontFamily: 'Cairo',
      brightness: Brightness.light,
    );
  }

// ---------------- DARK THEME ---------------- //
  static ThemeData _buildDarkTheme() {
    return ThemeData(
      fontFamily: 'Cairo',
      brightness: Brightness.dark,
    );
  }
}

LanguageController.dart

class LanguageController extends GetxController {
  Locale? initLang;

  AppServices appServices = Get.find();

  changeLang(String languageCode) {
    Locale locale = Locale(languageCode);
    appServices.box.write(AppStorageKeys.lang, languageCode);
    Get.updateLocale(locale);
  }

  @override
  void onInit() {
    String? storedLang = appServices.box.read(AppStorageKeys.lang);
    initLang = _getLocaleFromStoredLang(storedLang) ?? _getDefaultLocale();
    super.onInit();
  }

  /// Get the stored language if it exist
  Locale? _getLocaleFromStoredLang(String? storedLang) {
    return storedLang != null ? Locale(storedLang) : null;
  }

  /// Get the default device language
  Locale _getDefaultLocale() {
    return Locale(Get.deviceLocale!.languageCode);
  }
}

Upvotes: 0

Views: 64

Answers (1)

Aks
Aks

Reputation: 1696

You need to make sure that the ThemeData is updated whenever the language is changed. Currently, the theme is static, so even though you change the language, but the theme isn't being rebuilt.

Try this...

//Added fonts into assets folder

pubspec.yaml

...
  assets:
    - assets/fonts/Cairo/
    - assets/fonts/Poppins/

  fonts:
    - family: Poppins
      fonts:
        - asset: assets/fonts/Poppins/Poppins-Regular.ttf
        - asset: assets/fonts/Poppins/Poppins-Bold.ttf
          weight: 700
    - family: Cairo
      fonts:
        - asset: assets/fonts/Cairo/Cairo-Regular.ttf
        - asset: assets/fonts/Cairo/Cairo-Bold.ttf
          weight: 700

language_controller.dart

class LanguageController extends GetxController {
  Locale? initLang;
  RxString fontFamily = 'Cairo'.obs; // Default font family

  AppServices appServices = Get.find();

  changeLang(String languageCode) {
    Locale locale = Locale(languageCode);
    appServices.box.write(AppStorageKeys.lang, languageCode);

    // Update the font family based on the selected language
    if (languageCode == 'ar') {
      fontFamily.value = 'Cairo'; // Arabic font
    } else {
      fontFamily.value = 'Poppins'; // English or other font
    }

    Get.updateLocale(locale);
  }

  @override
  void onInit() {
    String? storedLang = appServices.box.read(AppStorageKeys.lang);
    initLang = _getLocaleFromStoredLang(storedLang) ?? _getDefaultLocale();

    // Set the initial font family based on the stored language
    if (storedLang == 'ar') {
      fontFamily.value = 'Cairo';
    } else {
      fontFamily.value = 'Poppins';
    }

    super.onInit();
  }

  /// Get the stored language if it exists
  Locale? _getLocaleFromStoredLang(String? storedLang) {
    return storedLang != null ? Locale(storedLang) : null;
  }

  /// Get the default device language
  Locale _getDefaultLocale() {
    return Locale(Get.deviceLocale!.languageCode);
  }
}

main.dart

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await init();

  runApp(const MyApp());
}

Future<void> init() async {
  await GetStorage.init();
  Get.put(AppServices());
  Get.put(LanguageController());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    final controller = Get.find<LanguageController>();
    return Obx(() => GetMaterialApp(
          themeMode: ThemeMode.system,
          theme: AppTheme.lightTheme(controller.fontFamily.value),
          darkTheme: AppTheme.darkTheme(controller.fontFamily.value),
          translations: AppTranslation(),
          locale: controller.initLang,
          home: const HomePage(),
        ));
  }
}

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Center(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.center,
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text('welcome'.tr), // For Welcome
              Text('login'.tr), // For Login
              Text('logout'.tr), // For Logout
              Text('profile'.tr), // For View Profile
              Text('settings'.tr), // For Settings
              TextButton(
                  onPressed: () {
                    Get.find<LanguageController>().changeLang('en');
                  },
                  child: const Text("Change to EN")),
              TextButton(
                  onPressed: () {
                    Get.find<LanguageController>().changeLang('ar');
                  },
                  child: const Text("Change to AR")),
            ],
          ),
        ),
      ),
    );
  }
}

app_theme.dart

class AppTheme {
  AppTheme._();

  static ThemeData lightTheme(String fontFamily) {
    return ThemeData(
        fontFamily: fontFamily,
        brightness: Brightness.light,
        scaffoldBackgroundColor: Colors.white);
  }

  static ThemeData darkTheme(String fontFamily) {
    return ThemeData(
        fontFamily: fontFamily,
        brightness: Brightness.dark,
        scaffoldBackgroundColor: Colors.black);
  }
}

app_translations.dart


class AppTranslation extends Translations {
  @override
  Map<String, Map<String, String>> get keys => {
        'en': {
          'welcome': 'Welcome to our app!',
          'login': 'Login',
          'logout': 'Logout',
          'profile': 'View Profile',
          'settings': 'Settings',
          'language_select': 'Select Language',
        },
        'ar': {
          'welcome': 'مرحبًا بك في تطبيقنا!',
          'login': 'تسجيل الدخول',
          'logout': 'تسجيل الخروج',
          'profile': 'عرض الملف الشخصي',
          'settings': 'الإعدادات',
          'language_select': 'اختر اللغة',
        }
      };
}

Here's the result: updating language

Upvotes: 1

Related Questions