效果图如下
为什么要设置国际化
- 系统组件默认为英文
- 各个平台统一标准
- TextField、 AlertDialog、 DatePicker
- 中英文转换:localization
1.添加依赖库
需要用到flutter_localizations包,在pubspec.yaml
文件中添加如下依赖
dependencies:
flutter:
sdk: flutter
flutter_localizations:
sdk: flutter
2.代码抽取封装
- 实现
LocalizationsDelegate
代理
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/cupertino.dart';
import 'package:fpdxapp/utils/localization/more.dart';
class HKLocalizationDelegate extends LocalizationsDelegate<CupertinoLocalizations> {
HKLocalizationDelegate();
///是否支持某个Local
///支持中文和英语
@override
bool isSupported(Locale locale) {
return ['zh', 'en'].contains(locale.languageCode);
}
///shouldReload的返回值决定当Localizations Widget重新build时,是否调用load方法重新加载Locale资源
@override
bool shouldReload(LocalizationsDelegate<CupertinoLocalizations> old) {
return false;
}
///根据locale,创建一个对象用于提供当前locale下的文本显示
///Flutter会调用此类加载相应的Locale资源类
@override
Future<CupertinoLocalizations> load(Locale locale) {
return SynchronousFuture<CupertinoLocalizations>(
MoreLocalization(locale)
);
}
static HKLocalizationDelegate delegate = HKLocalizationDelegate();
}
- 通过 MoreLocalization implements CupertinoLocalizations 设置
currentLocalized
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
class MoreLocalization implements CupertinoLocalizations{
final Locale locale;
MoreLocalization(this.locale);
/// 基于Map,根据当前语言的 languageCode: en或zh来获取对应的文案
static Map<String, BaseLanguage> _localValue = {
'en' : EnLanguage(),
'zh' : ChLanguage()
};
/// 返回当前的内容维护类
BaseLanguage get currentLocalized {
return _localValue[locale.languageCode];
}
///通过 Localizations.of(context,type) 加载当前的 FZLocalizations
static MoreLocalization of(BuildContext context) {
return CupertinoLocalizations.of(context);
/// 实现CupertinoLocalizations抽象类后,取不到对象,得换成CupertinoLocalizations.of(context);
// return Localizations.of(context, MoreLocalization);
}
@override
String get selectAllButtonLabel {
return currentLocalized.selectAllButtonLabel;
}
@override
String get pasteButtonLabel {
return currentLocalized.pasteButtonLabel;
}
@override
String get copyButtonLabel {
return currentLocalized.copyButtonLabel;
}
@override
String get cutButtonLabel {
return currentLocalized.cutButtonLabel;
}
@override
String get todayLabel {
return "今天";
}
static const List<String> _shortWeekdays = <String>[
'周一',
'周二',
'周三',
'周四',
'周五',
'周六',
'周日',
];
static const List<String> _shortMonths = <String>[
'Jan',
'Feb',
'Mar',
'Apr',
'May',
'Jun',
'Jul',
'Aug',
'Sep',
'Oct',
'Nov',
'Dec',
];
static const List<String> _months = <String>[
'01月',
'02月',
'03月',
'04月',
'05月',
'06月',
'07月',
'08月',
'09月',
'10月',
'11月',
'12月',
];
@override
String datePickerYear(int yearIndex) => yearIndex.toString() + "年";
@override
String datePickerMonth(int monthIndex) => _months[monthIndex - 1];
@override
String datePickerDayOfMonth(int dayIndex) => dayIndex.toString() + "日";
@override
String datePickerHour(int hour) => hour.toString();
@override
String datePickerHourSemanticsLabel(int hour) => hour.toString() + " 小时";
@override
String datePickerMinute(int minute) => minute.toString().padLeft(2, '0');
@override
String datePickerMinuteSemanticsLabel(int minute) {
return '1 分钟';
}
@override
String datePickerMediumDate(DateTime date) {
return '${_shortWeekdays[date.weekday - DateTime.monday]} '
'${_shortMonths[date.month - DateTime.january]} '
'${date.day.toString().padRight(2)}';
}
@override
DatePickerDateOrder get datePickerDateOrder => DatePickerDateOrder.ymd;
@override
DatePickerDateTimeOrder get datePickerDateTimeOrder => DatePickerDateTimeOrder.date_time_dayPeriod;
@override
String get anteMeridiemAbbreviation => 'AM';
@override
String get postMeridiemAbbreviation => 'PM';
@override
String get alertDialogLabel => '提示信息';
@override
String timerPickerHour(int hour) => hour.toString();
@override
String timerPickerMinute(int minute) => minute.toString();
@override
String timerPickerSecond(int second) => second.toString();
@override
String timerPickerHourLabel(int hour) => '时';
@override
String timerPickerMinuteLabel(int minute) => '分';
@override
String timerPickerSecondLabel(int second) => '秒';
}
/// 这个抽象类和它的实现类可以拉出去新建类
/// 中文和英语 语言内容维护
abstract class BaseLanguage {
String name;
String selectAllButtonLabel;
String pasteButtonLabel;
String copyButtonLabel;
String cutButtonLabel;
}
class EnLanguage implements BaseLanguage {
@override
String name = "This is English";
@override
String selectAllButtonLabel = "全选 英语";
@override
String pasteButtonLabel = "PASTE";
@override
String copyButtonLabel = "COPY";
@override
String cutButtonLabel = "CUT";
}
class ChLanguage implements BaseLanguage {
@override
String name = "这是中文";
@override
String selectAllButtonLabel = "全选";
@override
String pasteButtonLabel = "粘贴";
@override
String copyButtonLabel = "复制";
@override
String cutButtonLabel = "剪切";
}
- 如何使用
- 导入依赖库
import 'package:flutter_localizations/flutter_localizations.dart';
- 在Material中设置
localizationsDelegates、supportedLocales和localeListResolutionCallback
- 导入依赖库
MaterialApp(
title: 'App',
localizationsDelegates: [
/// 本地化的代理类
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
/// 注册我们的Delegate
HKLocalizationDelegate.delegate
],
supportedLocales: [
const Locale('en', 'US'), // 美国英语
const Locale('zh', 'CN'), // 中文简体
],
/// 监听系统语言切换
localeListResolutionCallback: (deviceLocale, supportedLocales){
print('deviceLocale: $deviceLocale');
// 系统语言是英语: deviceLocale: [en_CN, en_CN, zh_Hans_CN]
// 系统语言是中文: deviceLocale: [zh_CN, zh_Hans_CN, en_CN]
print('supportedLocales: $supportedLocales');
},
)
TextField光标不对齐
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
localizationsDelegates: [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: [const Locale('zh', 'CH'), const Locale('en', 'US')],
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatelessWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
padding: EdgeInsets.all(32),
child: Center(
child: TextField(
decoration: InputDecoration(hintText: '测试提示'),
),
),
),
);
}
}
如何修复TextField光标不对齐
TextField > style > textBaseline: TextBaseline.alphabetic
官方文档:
https://api.flutter.dev/flutter/flutter_localizations/flutter_localizations-library.html