|
| 1 | +# Localization Guide |
| 2 | + |
| 3 | +This guide explains how to enable and configure localization in the `calendar_view` package to support multiple languages in your Flutter application. |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +The package provides a flexible localization system that allows you to: |
| 8 | + |
| 9 | +- Display calendar strings (AM/PM, weekday names, etc.) in different languages |
| 10 | +- Support right-to-left (RTL) layouts for languages like Arabic and Hebrew |
| 11 | +- Customize number formatting for different locales |
| 12 | +- Dynamically switch between languages at runtime |
| 13 | + |
| 14 | +## Built-in Language Support |
| 15 | + |
| 16 | +The package includes **8 pre-configured languages** out of the box: |
| 17 | + |
| 18 | +| Language | Code | RTL | Localized Numbers | |
| 19 | +|----------|------|-----|-------------------| |
| 20 | +| English | `en` | No | No | |
| 21 | +| Spanish (Español) | `es` | No | No | |
| 22 | +| Arabic (العربية) | `ar` | Yes | Yes (٠-٩) | |
| 23 | +| French (Français) | `fr` | No | No | |
| 24 | +| German (Deutsch) | `de` | No | No | |
| 25 | +| Hindi (हिन्दी) | `hi` | No | Yes (०-९) | |
| 26 | +| Chinese (简体中文) | `zh` | No | No | |
| 27 | +| Japanese (日本語) | `ja` | No | No | |
| 28 | + |
| 29 | +You can use these built-in languages directly without any configuration! |
| 30 | + |
| 31 | +## Quick Start |
| 32 | + |
| 33 | +### Using Built-in Languages |
| 34 | + |
| 35 | +```dart |
| 36 | +import 'package:calendar_view/calendar_view.dart'; |
| 37 | +
|
| 38 | +void main() { |
| 39 | + // Switch to Spanish |
| 40 | + PackageStrings.setLocale('es'); |
| 41 | +
|
| 42 | + // Switch to Arabic (includes RTL and Arabic numerals) |
| 43 | + PackageStrings.setLocale('ar'); |
| 44 | +
|
| 45 | + // Switch to Hindi (includes Devanagari numerals) |
| 46 | + PackageStrings.setLocale('hi'); |
| 47 | +
|
| 48 | + runApp(MyApp()); |
| 49 | +} |
| 50 | +``` |
| 51 | + |
| 52 | +### Adding Custom Languages |
| 53 | + |
| 54 | +If you need a language that isn't built-in, you can easily add it: |
| 55 | + |
| 56 | +```dart |
| 57 | +import 'package:calendar_view/calendar_view.dart'; |
| 58 | +
|
| 59 | +void main() { |
| 60 | + // Add Portuguese |
| 61 | + PackageStrings.addLocaleObject( |
| 62 | + 'pt', |
| 63 | + CalendarLocalizations( |
| 64 | + am: 'AM', |
| 65 | + pm: 'PM', |
| 66 | + more: 'Mais', |
| 67 | + weekdays: ['S', 'T', 'Q', 'Q', 'S', 'S', 'D'], |
| 68 | + ), |
| 69 | + ); |
| 70 | +
|
| 71 | + // Add Russian |
| 72 | + PackageStrings.addLocaleObject( |
| 73 | + 'ru', |
| 74 | + CalendarLocalizations( |
| 75 | + am: 'ДП', |
| 76 | + pm: 'ПП', |
| 77 | + more: 'Ещё', |
| 78 | + weekdays: ['П', 'В', 'С', 'Ч', 'П', 'С', 'В'], |
| 79 | + ), |
| 80 | + ); |
| 81 | +
|
| 82 | + // Switch to custom language |
| 83 | + PackageStrings.setLocale('pt'); |
| 84 | +
|
| 85 | + runApp(MyApp()); |
| 86 | +} |
| 87 | +``` |
| 88 | + |
| 89 | +### Overriding Built-in Languages |
| 90 | + |
| 91 | +You can override any built-in language with custom values: |
| 92 | + |
| 93 | +```dart |
| 94 | +// Override the built-in Spanish with full weekday names |
| 95 | +PackageStrings.addLocaleObject( |
| 96 | + 'es', |
| 97 | + CalendarLocalizations( |
| 98 | + am: 'a. m.', |
| 99 | + pm: 'p. m.', |
| 100 | + more: 'Ver más', |
| 101 | + weekdays: ['Lun', 'Mar', 'Mié', 'Jue', 'Vie', 'Sáb', 'Dom'], |
| 102 | + ), |
| 103 | +); |
| 104 | +
|
| 105 | +PackageStrings.setLocale('es'); |
| 106 | +``` |
| 107 | + |
| 108 | +### Accessing Built-in Localizations |
| 109 | + |
| 110 | +You can access built-in localizations directly from `PackageStrings`: |
| 111 | + |
| 112 | +```dart |
| 113 | +CalendarLocalizations spanish = PackageStrings.spanish; |
| 114 | +CalendarLocalizations arabic = PackageStrings.arabic; |
| 115 | +CalendarLocalizations french = PackageStrings.french; |
| 116 | +CalendarLocalizations german = PackageStrings.german; |
| 117 | +CalendarLocalizations hindi = PackageStrings.hindi; |
| 118 | +CalendarLocalizations chinese = PackageStrings.chinese; |
| 119 | +CalendarLocalizations japanese = PackageStrings.japanese; |
| 120 | +
|
| 121 | +// Use them directly or customize them |
| 122 | +PackageStrings.addLocaleObject('es-custom', spanish); |
| 123 | +``` |
| 124 | + |
| 125 | +```dart |
| 126 | +// Set to Spanish |
| 127 | +PackageStrings.setLocale('es'); |
| 128 | +
|
| 129 | +// Set to Arabic |
| 130 | +PackageStrings.setLocale('ar'); |
| 131 | +
|
| 132 | +// Set back to English (default) |
| 133 | +PackageStrings.setLocale('en'); |
| 134 | +``` |
| 135 | + |
| 136 | +## API Reference |
| 137 | + |
| 138 | +### CalendarLocalizations |
| 139 | + |
| 140 | +A class that holds all localizable strings for the calendar. |
| 141 | + |
| 142 | +#### Constructor |
| 143 | + |
| 144 | +```dart |
| 145 | +const CalendarLocalizations({ |
| 146 | + required String am, // AM suffix (e.g., 'am', 'a. m.') |
| 147 | + required String pm, // PM suffix (e.g., 'pm', 'p. m.') |
| 148 | + required String more, // "More" text for additional events |
| 149 | + required List<String> weekdays, // Weekday abbreviations [Mon-Sun] |
| 150 | + List<String>? numbers, // Localized numbers 0-60 (61 elements) |
| 151 | + bool isRTL = false, // Right-to-left layout |
| 152 | +}); |
| 153 | +``` |
| 154 | + |
| 155 | +**Note:** If you provide a `numbers` array, it must contain exactly **61 elements** (representing numbers 0 through 60) for calendar usage (dates, hours, minutes). |
| 156 | + |
| 157 | +#### Factory Constructor |
| 158 | + |
| 159 | +You can also create localizations from a Map (useful for loading from JSON/ARB files): |
| 160 | + |
| 161 | +```dart |
| 162 | +factory CalendarLocalizations.fromMap(Map<String, dynamic> map) |
| 163 | +``` |
| 164 | + |
| 165 | +#### Built-in Locales |
| 166 | + |
| 167 | +The package includes a built-in English locale: |
| 168 | + |
| 169 | +```dart |
| 170 | +CalendarLocalizations.en // English (default) |
| 171 | +``` |
| 172 | + |
| 173 | +### PackageStrings |
| 174 | + |
| 175 | +A static class for managing calendar localizations at runtime. |
| 176 | + |
| 177 | +#### Methods |
| 178 | + |
| 179 | +| Method | Description | |
| 180 | +|--------|-------------| |
| 181 | +| `addLocaleObject(String locale, CalendarLocalizations localeObj)` | Register a new locale | |
| 182 | +| `setLocale(String locale)` | Set the active locale | |
| 183 | +| `localizeNumber(int number)` | Convert a number to localized string | |
| 184 | + |
| 185 | +#### Properties |
| 186 | + |
| 187 | +| Property | Description | |
| 188 | +|----------|-------------| |
| 189 | +| `currentLocale` | Get the current `CalendarLocalizations` object | |
| 190 | +| `selectedLocale` | Get the current locale code (e.g., 'en', 'es') | |
| 191 | + |
| 192 | +## Complete Integration Example |
| 193 | + |
| 194 | +Here's a complete example showing how to integrate localization with Flutter's built-in localization system: |
| 195 | + |
| 196 | +```dart |
| 197 | +import 'dart:ui'; |
| 198 | +import 'package:calendar_view/calendar_view.dart'; |
| 199 | +import 'package:flutter/material.dart'; |
| 200 | +import 'package:flutter_localizations/flutter_localizations.dart'; |
| 201 | +
|
| 202 | +void main() { |
| 203 | + runApp(MyApp()); |
| 204 | +} |
| 205 | +
|
| 206 | +class MyApp extends StatefulWidget { |
| 207 | + @override |
| 208 | + State<MyApp> createState() => _MyAppState(); |
| 209 | +} |
| 210 | +
|
| 211 | +class _MyAppState extends State<MyApp> { |
| 212 | + String _currentLocale = 'en'; |
| 213 | +
|
| 214 | + @override |
| 215 | + void initState() { |
| 216 | + super.initState(); |
| 217 | + // Initialize calendar localizations |
| 218 | + _initializeCalendarLocales(); |
| 219 | + } |
| 220 | +
|
| 221 | + void _initializeCalendarLocales() { |
| 222 | + // Register Spanish |
| 223 | + PackageStrings.addLocaleObject( |
| 224 | + 'es', |
| 225 | + CalendarLocalizations( |
| 226 | + am: 'a. m.', |
| 227 | + pm: 'p. m.', |
| 228 | + more: 'Más', |
| 229 | + weekdays: ['L', 'M', 'X', 'J', 'V', 'S', 'D'], |
| 230 | + ), |
| 231 | + ); |
| 232 | +
|
| 233 | + // Register Arabic with RTL |
| 234 | + PackageStrings.addLocaleObject( |
| 235 | + 'ar', |
| 236 | + CalendarLocalizations.fromMap({ |
| 237 | + 'am': 'ص', |
| 238 | + 'pm': 'م', |
| 239 | + 'more': 'المزيد', |
| 240 | + 'weekdays': ['ن', 'ث', 'ر', 'خ', 'ج', 'س', 'ح'], |
| 241 | + 'numbers': ['٠', '١', '٢', '٣', '٤', '٥', '٦', '٧', '٨', '٩'], |
| 242 | + 'isRTL': true, |
| 243 | + }), |
| 244 | + ); |
| 245 | + } |
| 246 | +
|
| 247 | + void _changeLocale(String locale) { |
| 248 | + setState(() { |
| 249 | + _currentLocale = locale; |
| 250 | + PackageStrings.setLocale(locale); |
| 251 | + }); |
| 252 | + } |
| 253 | +
|
| 254 | + @override |
| 255 | + Widget build(BuildContext context) { |
| 256 | + return CalendarControllerProvider( |
| 257 | + controller: EventController(), |
| 258 | + child: MaterialApp( |
| 259 | + locale: Locale(_currentLocale), |
| 260 | + localizationsDelegates: [ |
| 261 | + GlobalMaterialLocalizations.delegate, |
| 262 | + GlobalCupertinoLocalizations.delegate, |
| 263 | + GlobalWidgetsLocalizations.delegate, |
| 264 | + ], |
| 265 | + supportedLocales: [ |
| 266 | + Locale('en', ''), |
| 267 | + Locale('es', ''), |
| 268 | + Locale('ar', ''), |
| 269 | + ], |
| 270 | + home: Scaffold( |
| 271 | + appBar: AppBar( |
| 272 | + title: Text('Calendar Localization Demo'), |
| 273 | + actions: [ |
| 274 | + PopupMenuButton<String>( |
| 275 | + onSelected: _changeLocale, |
| 276 | + itemBuilder: (context) => [ |
| 277 | + PopupMenuItem(value: 'en', child: Text('English')), |
| 278 | + PopupMenuItem(value: 'es', child: Text('Español')), |
| 279 | + PopupMenuItem(value: 'ar', child: Text('العربية')), |
| 280 | + ], |
| 281 | + ), |
| 282 | + ], |
| 283 | + ), |
| 284 | + body: MonthView(), |
| 285 | + ), |
| 286 | + ), |
| 287 | + ); |
| 288 | + } |
| 289 | +} |
| 290 | +``` |
0 commit comments