app_localizations.dart 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. import 'dart:convert';
  2. import 'package:flutter/material.dart';
  3. import 'package:flutter/services.dart';
  4. class AppLocalizations {
  5. final Locale locale;
  6. final Map<String, String> _strings;
  7. AppLocalizations(this.locale, this._strings);
  8. String get(String key) => _strings[key] ?? key;
  9. String getString(String key, {Map<String, String>? args}) {
  10. var value = _strings[key] ?? key;
  11. if (args != null) {
  12. for (final entry in args.entries) {
  13. value = value.replaceAll('\${${entry.key}}', entry.value);
  14. }
  15. }
  16. return value;
  17. }
  18. static AppLocalizations of(BuildContext context) {
  19. return Localizations.of<AppLocalizations>(context, AppLocalizations)!;
  20. }
  21. static Future<AppLocalizations> load(Locale locale) async {
  22. String langCode;
  23. if (locale.languageCode == 'zh') {
  24. langCode = locale.countryCode == 'TW' ? 'zh_TW' : 'zh_CN';
  25. } else {
  26. langCode = locale.languageCode;
  27. }
  28. final path = 'assets/i18n/$langCode.json';
  29. final jsonStr = await rootBundle.loadString(path);
  30. final raw = jsonDecode(jsonStr) as Map<String, dynamic>;
  31. final flat = <String, String>{};
  32. void flatten(Map<String, dynamic> map) {
  33. for (final entry in map.entries) {
  34. if (entry.value is Map<String, dynamic>) {
  35. flatten(entry.value as Map<String, dynamic>);
  36. } else {
  37. flat[entry.key] = entry.value.toString();
  38. }
  39. }
  40. }
  41. flatten(raw);
  42. return AppLocalizations(locale, flat);
  43. }
  44. static const LocalizationsDelegate<AppLocalizations> delegate =
  45. _AppLocalizationsDelegate();
  46. }
  47. class _AppLocalizationsDelegate
  48. extends LocalizationsDelegate<AppLocalizations> {
  49. const _AppLocalizationsDelegate();
  50. @override
  51. bool isSupported(Locale locale) => ['zh', 'en'].contains(locale.languageCode);
  52. @override
  53. Future<AppLocalizations> load(Locale locale) => AppLocalizations.load(locale);
  54. @override
  55. bool shouldReload(_AppLocalizationsDelegate old) => false;
  56. }