面试题答案
一键面试创建语言资源文件
- 安装依赖:在
pubspec.yaml
文件中添加flutter_localizations
依赖,这是Flutter官方提供的国际化支持库。
dependencies:
flutter_localizations:
sdk: flutter
- 创建资源文件:在项目根目录下创建
lib/l10n
文件夹(可自定义)。在该文件夹内,创建不同语言的.arb
文件,例如:app_en.arb
用于英文app_zh.arb
用于中文- 文件名遵循
app_{语言代码}.arb
格式。
- 编写资源内容:以
app_en.arb
为例,内容格式如下:
{
"welcomeMessage": "Welcome",
"@welcomeMessage": {
"description": "The message shown on the welcome screen"
}
}
@welcomeMessage
部分是对 welcomeMessage
的描述,有助于翻译人员理解该字符串用途。
在代码中初始化国际化功能
- 导入包:在
main.dart
文件中导入flutter_localizations
包:
import 'package:flutter_localizations/flutter_localizations.dart';
- 初始化
LocalizationsDelegates
:在MaterialApp
中配置localizationsDelegates
和supportedLocales
。
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
localizationsDelegates: [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
// 自定义的本地化代理
AppLocalizations.delegate,
],
supportedLocales: [
const Locale('en', ''),
const Locale('zh', ''),
],
home: HomePage(),
);
}
}
- 创建自定义
LocalizationsDelegate
:在lib/l10n
文件夹下创建app_localizations.dart
文件。
import 'dart:ui';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart' show rootBundle;
import 'package:flutter_localizations/flutter_localizations.dart';
class AppLocalizations {
final Locale locale;
AppLocalizations(this.locale);
static AppLocalizations of(BuildContext context) {
return Localizations.of<AppLocalizations>(context, AppLocalizations)!;
}
late Map<String, String> _localizedValues;
Future<bool> load() async {
String jsonString = await rootBundle.loadString('l10n/app_${locale.languageCode}.arb');
Map<String, dynamic> jsonMap = json.decode(jsonString);
_localizedValues = jsonMap.map((key, value) => MapEntry(key, value.toString()));
return true;
}
String translate(String key) {
return _localizedValues[key] ?? key;
}
}
class AppLocalizationsDelegate extends LocalizationsDelegate<AppLocalizations> {
const AppLocalizationsDelegate();
@override
bool isSupported(Locale locale) => ['en', 'zh'].contains(locale.languageCode);
@override
Future<AppLocalizations> load(Locale locale) async {
AppLocalizations localizations = AppLocalizations(locale);
await localizations.load();
return localizations;
}
@override
bool shouldReload(AppLocalizationsDelegate old) => false;
}
在代码中使用国际化功能
- 获取翻译字符串:在需要使用翻译的地方,通过
AppLocalizations.of(context).translate('key')
获取翻译后的字符串。
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(AppLocalizations.of(context).translate('welcomeMessage')),
),
body: Center(
child: Text(AppLocalizations.of(context).translate('welcomeMessage')),
),
);
}
}
- 动态切换语言:可以通过
Provider
或InheritedWidget
等方式管理语言状态,并调用Navigator.of(context).pushReplacement
或setState
等方法刷新界面以应用新语言。例如,假设存在一个LanguageProvider
:
class LanguageProvider with ChangeNotifier {
Locale _locale = const Locale('en', '');
Locale get locale => _locale;
void setLocale(Locale locale) {
_locale = locale;
notifyListeners();
}
}
在切换语言的按钮点击事件中:
ElevatedButton(
onPressed: () {
Locale newLocale = const Locale('zh', '');
Provider.of<LanguageProvider>(context, listen: false).setLocale(newLocale);
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (context) => HomePage()),
);
},
child: Text('Switch to Chinese'),
)