MST

星途 面试题库

面试题:Flutter 中如何实现基础的语言国际化

在Flutter项目中,简述实现不同语言切换的基本步骤,包括如何创建语言资源文件、如何在代码中初始化和使用国际化功能。
24.0万 热度难度
前端开发Flutter

知识考点

AI 面试

面试题答案

一键面试

创建语言资源文件

  1. 安装依赖:在 pubspec.yaml 文件中添加 flutter_localizations 依赖,这是Flutter官方提供的国际化支持库。
dependencies:
  flutter_localizations:
    sdk: flutter
  1. 创建资源文件:在项目根目录下创建 lib/l10n 文件夹(可自定义)。在该文件夹内,创建不同语言的 .arb 文件,例如:
    • app_en.arb 用于英文
    • app_zh.arb 用于中文
    • 文件名遵循 app_{语言代码}.arb 格式。
  2. 编写资源内容:以 app_en.arb 为例,内容格式如下:
{
  "welcomeMessage": "Welcome",
  "@welcomeMessage": {
    "description": "The message shown on the welcome screen"
  }
}

@welcomeMessage 部分是对 welcomeMessage 的描述,有助于翻译人员理解该字符串用途。

在代码中初始化国际化功能

  1. 导入包:在 main.dart 文件中导入 flutter_localizations 包:
import 'package:flutter_localizations/flutter_localizations.dart';
  1. 初始化 LocalizationsDelegates:在 MaterialApp 中配置 localizationsDelegatessupportedLocales
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(),
    );
  }
}
  1. 创建自定义 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;
}

在代码中使用国际化功能

  1. 获取翻译字符串:在需要使用翻译的地方,通过 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')),
      ),
    );
  }
}
  1. 动态切换语言:可以通过 ProviderInheritedWidget 等方式管理语言状态,并调用 Navigator.of(context).pushReplacementsetState 等方法刷新界面以应用新语言。例如,假设存在一个 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'),
)