1. 创建自定义 GlobalMaterialLocalizations
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:kittlenapp/utils/base/date_time_util.dart';
class MyMaterialLocalizationZh extends MaterialLocalizationZh {
MyMaterialLocalizationZh(
{super.localeName = 'my_local',
required super.fullYearFormat,
required super.compactDateFormat,
required super.shortDateFormat,
required super.mediumDateFormat,
required super.longDateFormat,
required super.yearMonthFormat,
required super.shortMonthDayFormat,
required super.decimalFormat,
required super.twoDigitZeroPaddedFormat});
@override
String formatCompactDate(DateTime date) {
return DateTimeUtil.formatDate(date);
}
@override
DateTime? parseCompactDate(String? inputString) {
if (inputString == null) {
return null;
}
final List<String> inputParts = inputString.split('-');
if (inputParts.length != 3) {
return null;
}
final int? year = int.tryParse(inputParts[0], radix: 10);
if (year == null || year < 1) {
return null;
}
final int? month = int.tryParse(inputParts[1], radix: 10);
if (month == null || month < 1 || month > 12) {
return null;
}
final int? day = int.tryParse(inputParts[2], radix: 10);
if (day == null || day < 1 || day > _getDaysInMonth(year, month)) {
return null;
}
return DateTime(year, month, day);
}
int _getDaysInMonth(int year, int month) {
if (month == DateTime.february) {
final bool isLeapYear = (year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0);
if (isLeapYear) {
return 29;
}
return 28;
}
const List<int> daysInMonth = <int>[31, -1, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
return daysInMonth[month - 1];
}
}
2.创建对应的LocalizationsDelegate管理本地配置
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart' as intl;
import 'package:flutter_localizations/src/l10n/generated_material_localizations.dart';
import 'package:flutter_localizations/src/utils/date_localizations.dart' as util;
import 'package:kittlenapp/localzations/my_material_localization_zh.dart';
class MyLocalizationsDelegate extends LocalizationsDelegate<MaterialLocalizations> {
static const LocalizationsDelegate<MaterialLocalizations> delegate = MyLocalizationsDelegate();
const MyLocalizationsDelegate();
@override
bool isSupported(Locale locale) => locale.languageCode == 'my_local';
static Future<MaterialLocalizations>? _loadedTranslations;
@override
Future<MaterialLocalizations> load(Locale locale) {
assert(isSupported(locale));
if (_loadedTranslations != null) {
return _loadedTranslations!;
}
util.loadDateIntlDataIfNotLoaded();
Locale baseLocal = Locale('zh', 'CH');
final String localeName = intl.Intl.canonicalizedLocale(baseLocal.toString());
assert(
baseLocal.toString() == localeName,
'Flutter does not support the non-standard locale form $baseLocal (which '
'might be $localeName',
);
intl.DateFormat fullYearFormat;
intl.DateFormat compactDateFormat;
intl.DateFormat shortDateFormat;
intl.DateFormat mediumDateFormat;
intl.DateFormat longDateFormat;
intl.DateFormat yearMonthFormat;
intl.DateFormat shortMonthDayFormat;
if (intl.DateFormat.localeExists(localeName)) {
fullYearFormat = intl.DateFormat.y(localeName);
compactDateFormat = intl.DateFormat.yMd(localeName);
shortDateFormat = intl.DateFormat.yMMMd(localeName);
mediumDateFormat = intl.DateFormat.MMMEd(localeName);
longDateFormat = intl.DateFormat.yMMMMEEEEd(localeName);
yearMonthFormat = intl.DateFormat.yMMMM(localeName);
shortMonthDayFormat = intl.DateFormat.MMMd(localeName);
} else if (intl.DateFormat.localeExists(baseLocal.languageCode)) {
fullYearFormat = intl.DateFormat.y(baseLocal.languageCode);
compactDateFormat = intl.DateFormat.yMd(baseLocal.languageCode);
shortDateFormat = intl.DateFormat.yMMMd(baseLocal.languageCode);
mediumDateFormat = intl.DateFormat.MMMEd(baseLocal.languageCode);
longDateFormat = intl.DateFormat.yMMMMEEEEd(baseLocal.languageCode);
yearMonthFormat = intl.DateFormat.yMMMM(baseLocal.languageCode);
shortMonthDayFormat = intl.DateFormat.MMMd(baseLocal.languageCode);
} else {
fullYearFormat = intl.DateFormat.y();
compactDateFormat = intl.DateFormat.yMd();
shortDateFormat = intl.DateFormat.yMMMd();
mediumDateFormat = intl.DateFormat.MMMEd();
longDateFormat = intl.DateFormat.yMMMMEEEEd();
yearMonthFormat = intl.DateFormat.yMMMM();
shortMonthDayFormat = intl.DateFormat.MMMd();
}
intl.NumberFormat decimalFormat;
intl.NumberFormat twoDigitZeroPaddedFormat;
if (intl.NumberFormat.localeExists(localeName)) {
decimalFormat = intl.NumberFormat.decimalPattern(localeName);
twoDigitZeroPaddedFormat = intl.NumberFormat('00', localeName);
} else if (intl.NumberFormat.localeExists(locale.languageCode)) {
decimalFormat = intl.NumberFormat.decimalPattern(locale.languageCode);
twoDigitZeroPaddedFormat = intl.NumberFormat('00', locale.languageCode);
} else {
decimalFormat = intl.NumberFormat.decimalPattern();
twoDigitZeroPaddedFormat = intl.NumberFormat('00');
}
_loadedTranslations = SynchronousFuture(MyMaterialLocalizationZh(
fullYearFormat: fullYearFormat,
compactDateFormat: compactDateFormat,
shortDateFormat: shortDateFormat,
mediumDateFormat: mediumDateFormat,
longDateFormat: longDateFormat,
yearMonthFormat: yearMonthFormat,
shortMonthDayFormat: shortMonthDayFormat,
decimalFormat: decimalFormat,
twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat));
return _loadedTranslations!;
}
@override
bool shouldReload(MyLocalizationsDelegate old) => false;
@override
String toString() => 'GlobalMaterialLocalizations.delegate(${kMaterialSupportedLanguages.length} locales)';
}
3.在main.dar中补充该LocalizationsDelegate
class _MyApp extends State<MyApp> with WidgetsBindingObserver {
@override
Widget build(BuildContext context) {
MainInit.buildInit(context);
final ThemeData theme = ThemeData();
return MaterialApp(
localizationsDelegates: const [
MyLocalizationsDelegate.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
]
}
4. 注意
pubspec.yaml
dependencies:
flutter:
sdk: flutter
flutter_localizations:
sdk: flutter
使用时
Localizations.override(
context: context,
locale: Locale('my_local', 'CH'),
child: widget,
);