Localization Module
The Localization module creates a complete internationalization system for your app, supporting multiple languages with state management integration.
Generated Structure
lib/core/localization/
├── generated/
│ └── app_localizations.dart (generated by Flutter)
├── l10n/
│ ├── app_en.arb
│ ├── app_es.arb
│ └── l10n.dart
├── widgets/
│ └── language_selector.dart
└── localization.dart
Plus state management-specific files like:
bloc/locale_bloc.dart
(for BLoC)providers/localization_provider.dart
(for Provider)controllers/localization_controller.dart
(for GetX)
Key Components
1. ARB Files (app_en.arb
, app_es.arb
, etc.)
Define translated strings for each supported language:
// app_en.arb
{
"@@locale": "en",
"appTitle": "My App",
"welcome": "Welcome",
"hello": "Hello, {name}",
"@hello": {
"description": "A welcome message with a name parameter",
"placeholders": {
"name": {
"type": "String",
"example": "John"
}
}
},
// Other strings...
}
// app_es.arb
{
"@@locale": "es",
"appTitle": "Mi Aplicación",
"welcome": "Bienvenido",
"hello": "Hola, {name}",
// Other translations...
}
2. L10n Configuration (l10n.dart
)
Defines supported locales:
class L10n {
L10n._();
/// All supported locales in the app
static const supportedLocales = [
Locale('en'),
Locale('es'),
// Add more locales as needed
];
}
3. Localization Extensions (localization.dart
)
Provides easy access to translated strings and utility methods:
/// Extension method to get localized strings easier
extension LocalizationExtension on BuildContext {
/// Get the translation strings instance
AppLocalizations get l10n => AppLocalizations.of(this);
}
/// Utility methods for localization
class Localization {
Localization._();
/// Get all available locales
static List<Locale> get supportedLocales => AppLocalizations.supportedLocales;
/// Get all localization delegates
static List<LocalizationsDelegate<dynamic>> get localizationDelegates => [
AppLocalizations.delegate,
...GlobalMaterialLocalizations.delegates,
];
/// Get a friendly display name for a locale
static String getLanguageName(String languageCode) {
switch (languageCode) {
case 'es':
return 'Español';
// Other languages...
case 'en':
default:
return 'English';
}
}
/// Get a flag emoji for a language
static String getLanguageFlag(String languageCode) {
switch (languageCode) {
case 'es':
return '🇪🇸';
// Other languages...
case 'en':
default:
return '🇺🇸';
}
}
}
4. Language Selector Widget (language_selector.dart
)
A reusable widget for language selection:
class LanguageSelector extends StatelessWidget {
/// Callback when language changes
final Function(Locale) onChanged;
const LanguageSelector({Key? key, required this.onChanged}) : super(key: key);
@override
Widget build(BuildContext context) {
final currentLocale = Localizations.localeOf(context);
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: Text(
context.l10n.language,
style: Theme.of(context).textTheme.titleMedium,
),
),
const SizedBox(height: 8),
...L10n.supportedLocales.map((locale) {
final isSelected = currentLocale.languageCode == locale.languageCode;
return ListTile(
leading: Text(
Localization.getLanguageFlag(locale.languageCode),
style: const TextStyle(fontSize: 24),
),
title: Text(Localization.getLanguageName(locale.languageCode)),
trailing: isSelected
? const Icon(Icons.check, color: Colors.green)
: null,
onTap: () {
if (!isSelected) {
onChanged(locale);
}
},
);
}).toList(),
],
);
}
}
5. State Management Integration
BLoC Example:
// Events
abstract class LocaleEvent extends Equatable {
const LocaleEvent();
@override
List<Object> get props => [];
}
class ChangeLocaleEvent extends LocaleEvent {
final String languageCode;
const ChangeLocaleEvent(this.languageCode);
@override
List<Object> get props => [languageCode];
}
class LoadLocaleEvent extends LocaleEvent {}
// State
class LocaleState extends Equatable {
final Locale locale;
const LocaleState(this.locale);
@override
List<Object> get props => [locale];
}
// BLoC
class LocaleBloc extends Bloc<LocaleEvent, LocaleState> {
static const String LOCALE_KEY = 'app_locale';
LocaleBloc() : super(const LocaleState(Locale('en'))) {
on<ChangeLocaleEvent>(_onChangeLocale);
on<LoadLocaleEvent>(_onLoadLocale);
// Load saved locale when bloc is created
add(LoadLocaleEvent());
}
// Event handlers...
}
// Extension for easy use with BuildContext
extension LocaleBlocExtension on BuildContext {
void changeLocale(String languageCode) {
read<LocaleBloc>().add(ChangeLocaleEvent(languageCode));
}
Locale get locale => read<LocaleBloc>().state.locale;
}
How to Use the Localization System
Access translated strings:
// Access a simple string
Text(context.l10n.welcome)
// With parameters
Text(context.l10n.hello('John'))
// Plurals
Text(context.l10n.counter(itemCount))
Change the language:
// With BLoC
context.changeLocale('es');
// With Provider
context.read<LocalizationProvider>().setLocaleByLanguageCode('es');
// With GetX
Get.find<LocalizationController>().setLocale('es');
Add localization to MaterialApp:
return MaterialApp(
// Other properties...
supportedLocales: Localization.supportedLocales,
localizationsDelegates: Localization.localizationDelegates,
locale: currentLocale, // From your state management
);
Customizing the Localization System
- Add New Languages: Create new ARB files (
app_fr.arb
, etc.) and add the locale toL10n.supportedLocales
- Add New Strings: Update all ARB files with new string entries
- Customize Language Selector: Modify the
LanguageSelector
widget for your UI needs - Country-Specific Locales: Support country variants with full locale codes (
Locale('en', 'US')
)
Push Notification Module
The Push Notification module creates a complete notification system using Firebase Cloud Messaging and Flutter Local Notifications.
Generated Structure
lib/core/notifications/
├── models/
│ └── push_notification_model.dart
├── services/
│ ├── fcm_service.dart
│ └── local_notification_service.dart
└── notification_handler.dart
Key Components
1. Notification Model (push_notification_model.dart
)
Defines the data structure for notifications:
class PushNotificationModel {
final String title;
final String body;
final String? imageUrl;
final String? payload;
PushNotificationModel({
required this.title,
required this.body,
this.imageUrl,
this.payload,
});
factory PushNotificationModel.fromJson(Map<String, dynamic> json) {
return PushNotificationModel(
title: json['title'] ?? '',
body: json['body'] ?? '',
imageUrl: json['imageUrl'],
payload: json['payload'],
);
}
Map<String, dynamic> toJson() {
return {
'title': title,
'body': body,
'imageUrl': imageUrl,
'payload': payload,
};
}
}
2. FCM Service (fcm_service.dart
)
Handles Firebase Cloud Messaging integration:
class FCMService {
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance;
final LocalNotificationService _localNo