Skip to content

Software Development at Program Tom LTD

Place for coding, programming, development and software in general.

Menu
  • Blog
  • PDF Booklets
  • Dev Utils & Content
  • Java Spring Boot Or Web Apps
  • English
    • български
    • English
    • Español
    • Português
    • हिन्दी
    • Русский
    • Deutsch
    • Français
    • Italiano
    • العربية
  • About Us
  • Flutter Apps
Menu
Internationalizing Flutter app from anywhere - with arb files & plain InheritedWidget

Internationalizing Flutter app with plain InheritedWidget

Posted on December 31, 2024 by Toma Velev

In this article I will be Implementing Internationalizing Flutter app from anywhere (within the app) with the help of arb files, plain InheritedWidget. I’ll be taking advantage and building on a previous article Flutter Localization with intl https://programtom.com/dev/2024/10/14/flutter-localization-with-intl/.

MaterialApp fields

Locale in a Flutter App is set through a locale field present in the Master widgets MaterialApp and CupertinoApp. A Very minimal Root Widget would look like:

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

  @override
  Widget build(BuildContext context) => LocaleManagerWidget(
        builder: (context, locale) => MaterialApp(
          locale: locale,
          localizationsDelegates: AppLocalizations.localizationsDelegates,
          supportedLocales: AppLocalizations.supportedLocales,
          theme: ThemeData(
              colorScheme: ColorScheme.fromSeed(seedColor: Colors.black),
              useMaterial3: true,
              extensions: [
                WidgetToolkitTheme.light(),
                ItemPickerTheme.light(),
              ]),
          home: const LoadingScreen(),
        ),
      );
}

(Custom) LocaleManagerWidget

I’ve coded a StatefulWidget that handles

  • Loading State from cache at start
  • Update Locale after change from inner Widgets,
  • Pass down the locale – so the Master Widget may delegate it to the engine. I’m using a custom Widget Builder
import 'package:flutter/material.dart';

import '../common/ds/shared_preferences_data_source.dart';
import 'local_manager_inherited_widget.dart';

class LocaleManagerWidget extends StatefulWidget {
  final Function(dynamic context, Locale locale) builder;

  const LocaleManagerWidget({
    super.key,
    required this.builder,
  });

  @override
  State<LocaleManagerWidget> createState() => _LocaleManagerWidgetState();
}

class _LocaleManagerWidgetState extends State<LocaleManagerWidget> {
  Locale _locale = const Locale('en'); // Default locale

  void _setLocale(Locale locale) {
    setState(() {
      _locale = locale;
    });
  }

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

  Future<void> _load() async {
    var userLanguage = await SharedPreferencesDataSource().get("userLanguage");
    setState(() {
      _locale = Locale(userLanguage ?? 'en');
    });
  }

  @override
  Widget build(BuildContext context) => LocaleManagerInheritedWidget(
        locale: _locale,
        setLocale: _setLocale,
        child: widget.builder(context, _locale),
      );
}

I’ll not get into the Data Source as it may be memory, file, shared_preferences, secure_storage, or whatever you’d like.

LocaleManagerInheritedWidget

Flutter Engineers around the world has gone a long way to complicate building on InheritedWidget to create State Management solutions on

  • Provider
  • Bloc
  • Riverpod
  • ioc_contaienr
  • and more

A simple way to expose something to the child widgets – get or setting locale look like this:

import 'package:flutter/material.dart';

class LocaleManagerInheritedWidget extends InheritedWidget {
  final Locale locale;
  final Function(Locale) setLocale;

  const LocaleManagerInheritedWidget({
    super.key,
    required this.locale,
    required this.setLocale,
    required super.child,
  });

  static LocaleManagerInheritedWidget? of(BuildContext context) {
    return context
        .dependOnInheritedWidgetOfExactType<LocaleManagerInheritedWidget>();
  }

  @override
  bool updateShouldNotify(covariant LocaleManagerInheritedWidget oldWidget) {
    return locale != oldWidget.locale;
  }
}

 Accessing Internationalizing data – from nodes in the Flutter Widget Tree

Accessing nodes in any widget underneed is as plain as

LocaleManagerInheritedWidget.of(context)?.setLocale(Locale(newLang));
//or LocaleManagerInheritedWidget.of(context)?.locale // to get it
  • What are ways to Optimize the backend endpoints in Spring Boot
  • Flutter image flickers
  • Could a Flutter App save a Flag even after uninstall
  • Could iOS flutter app logs be viewed while running in release mode – started after previous closed state
  • 6 Addictive Mobile Game Ideas Inspired by Flappy Bird’s Simplicity

Categories

  • Apps (20)
  • ChatGPT (19)
  • Choosing a Framework (38)
  • Flutter (206)
  • Graphical User Interface (13)
  • Marketing (114)
  • Software Development (270)
  • Spring (43)
  • StartUp (21)
  • Uncategorized (4)
  • Uncategorized (15)
  • Vaadin (14)

Tags

Algorithms (9) crypto (29) flutterdev (39) General (86) Java (7) QR & Bar Codes (3) Software Dev Choices (33) Spring Boot (1) standards (1) Theme (3) User Authentication & Authorization (9) User Experience (10) Utilities (19) WordPress (11)

Product categories

  • All Technologies (83)
    • Flutter Apps (23)
    • GPT (4)
    • Java (38)
    • Native Android (3)
    • PHP (9)
    • Spring (Boot) / Quarkus (35)
    • Utils (15)
    • Vaadin 24+ (27)
    • Vaadin 8 (1)
  • Apps (18)
    • Employees DB (1)
    • Notes (6)
    • Personal Budget (1)
    • Recipes Book (1)
    • Stuff Organizer (1)
    • To-Do (2)
  • PDF Books (3)
  • Source Code Generators (8)

Recent Posts

  • What are ways to Optimize the backend endpoints in Spring Boot
  • Flutter image flickers
  • Could a Flutter App save a Flag even after uninstall
  • Could iOS flutter app logs be viewed while running in release mode – started after previous closed state
  • 6 Addictive Mobile Game Ideas Inspired by Flappy Bird’s Simplicity

Post Categories

  • Apps (20)
  • ChatGPT (19)
  • Choosing a Framework (38)
  • Flutter (206)
  • Graphical User Interface (13)
  • Marketing (114)
  • Software Development (270)
  • Spring (43)
  • StartUp (21)
  • Uncategorized (4)
  • Uncategorized (15)
  • Vaadin (14)