Flutter本地化管理插件yaml_localizations的使用

Flutter本地化管理插件yaml_localizations的使用

yaml_localizations 是一个用于 Flutter 的最小化 YAML 本地化包。

YAML 是一种人类可读的配置文件格式,具有简洁的语法。它允许你将字符串表示为键值对,除了其他类型外。

YAML 是 Flutter 的 pubspec.yaml 文件使用的格式。

安装

在你的 pubspec.yaml 文件中添加 yaml_localizationsflutter_localizations 依赖:

dependencies:
  flutter_localizations:
    sdk: flutter
  yaml_localizations:

添加语言特定的 YAML 文件

为每种支持的语言添加一个 YAML 文件,并将其路径描述在 pubspec.yaml 中。

flutter:
  assets:
    - assets/yaml_translations/

YAML 文件名必须与 supportedLocales 中描述的语言标签匹配。

例如,如果 Locale('en', 'US') 必须有一个对应的 assetPath/en-US.yaml 文件。

添加 localizationDelegatessupportedLocales

MaterialApp 中添加 YamlLocalizationsDelegate 并设置 supportedLocales 使用语言/国家代码。

MaterialApp(
  localizationsDelegates: [
    // 全局委托
    ...GlobalMaterialLocalizations.delegates,
    // YAML本地化
    YamlLocalizationsDelegate(
      path: 'assets/yaml_translations',
      assetBundle: DefaultAssetBundle.of(context),
    ),
  ],
  supportedLocales: [
    Locale('en', 'GB'),
    Locale('en', 'US'),
    Locale('en'),
    Locale('nb'),
  ],
  theme: ThemeData(
    primarySwatch: Colors.blue,
    visualDensity: VisualDensity.adaptivePlatformDensity,
  ),
  home: const MyHomePage(),
)

iOS 注意事项

ios/Runner/Info.plist 中添加支持的语言,如下所示:

<key>CFBundleLocalizations</key>
<array>
    <string>en-GB</string>
    <string>en</string>
    <string>nb</string>
</array>

YAML 格式

以下是一个 YAML 文件的例子:

Hi: Hi
Text: |
  There once was a tall man from Ealing
  Who got on a bus to Darjeeling
      It said on the door
      "Please don't sit on the floor"
  So he carefully sat on the ceiling
Long: &gt;
  Wrapped text
  will be folded
  into a single
  paragraph

  Blank lines denote
  paragraph breaks

提示:YAML 支持多种表达字符串的方式。使用竖线字符 (|) 表示字符串将跨越多行。使用大于号 (>) 来拆分长行。

API

使用以下方式来翻译字符串:

YamlLocalizations.of(context)?.string('Hi')

你可以通过扩展方法轻松地向 String 类添加功能,如下所示:

extension LocalizedString on String {
  String tr(BuildContext context) => YamlLocalizations.of(context)!.string(this);
}

这样你就可以像这样使用它:

'Hi'.tr(context)

示例

完整的示例代码如下:

import 'package:flutter/material.dart';
import 'package:yaml_localizations/yaml_localizations.dart';
import 'package:flutter_localizations/flutter_localizations.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      localizationsDelegates: [
        ...GlobalMaterialLocalizations.delegates,
        YamlLocalizationsDelegate(
            path: 'assets/yaml_translations',
            assetBundle: DefaultAssetBundle.of(context)),
      ],
      supportedLocales: const [
        Locale('en', 'GB'),
        Locale('en', 'US'),
        Locale('en'),
        Locale('nb'),
      ],
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key}) : super(key: key);

  [@override](/user/override)
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('yaml_localizations'),
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.start,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(YamlLocalizations.of(context)?.string('Hi') ?? ''),
          const SizedBox(height: 12),
          Text(YamlLocalizations.of(context)?.string('Text') ?? ''),
          const SizedBox(height: 12),
          Text(YamlLocalizations.of(context)?.string('Long') ?? ''),
        ],
      ),
    );
  }
}

更多关于Flutter本地化管理插件yaml_localizations的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter本地化管理插件yaml_localizations的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter项目中使用yaml_localizations插件进行本地化管理的代码示例。需要注意的是,yaml_localizations并不是一个官方或广泛认可的Flutter插件名称。通常,Flutter本地化是通过flutter_localizations包和自定义的LocalizationsDelegate来实现的。不过,我会假设你提到的yaml_localizations是一个假设的或自定义的插件,用于从YAML文件中加载本地化字符串。

假设我们有一个名为yaml_localizations的自定义插件,它允许我们从YAML文件中加载本地化资源。以下是如何在Flutter项目中使用这样的插件的示例。

1. 创建YAML本地化文件

首先,我们需要创建包含本地化字符串的YAML文件。例如,我们可以创建en.yamlzh.yaml文件:

en.yaml

greeting: Hello, World!
farewell: Goodbye!

zh.yaml

greeting: 你好,世界!
farewell: 再见!

2. 创建自定义LocalizationsDelegate

接下来,我们需要创建一个自定义的LocalizationsDelegate来加载这些YAML文件。由于yaml_localizations是假设的,我们将创建一个名为YamlLocalizations的类来模拟这个过程。

import 'dart:convert';
import 'package:flutter/material.dart';
import 'dart:async';

class YamlLocalizations {
  static YamlLocalizations of(BuildContext context) {
    return Localizations.of<YamlLocalizations>(context, YamlLocalizations)!;
  }

  final Map<String, String> _localizations;

  YamlLocalizations(this._localizations);

  String get text(String key) {
    return _localizations[key] ?? key; // Return key if translation is not found
  }
}

class YamlLocalizationDelegate extends LocalizationsDelegate<YamlLocalizations> {
  final String locale;
  final String assetBasePath;

  YamlLocalizationDelegate({required this.locale, required this.assetBasePath});

  @override
  bool isSupported(Locale locale) {
    // Check if the locale is supported by comparing the language code
    return locale.languageCode == locale.substring(0, 2);
  }

  @override
  Future<YamlLocalizations> load(Locale locale) async {
    String languageCode = locale.languageCode;
    String fileName = '$languageCode.yaml';
    String fileContent = await rootBundle.loadString('$assetBasePath/$fileName');
    Map<String, String> localizations =
        jsonDecode(fileContent) as Map<String, String>; // YAML is loaded as JSON for simplicity in this example
    return YamlLocalizations(localizations);
  }

  @override
  bool shouldReload(YamlLocalizationDelegate oldDelegate) {
    return oldDelegate.locale != locale || oldDelegate.assetBasePath != assetBasePath;
  }
}

注意:上面的代码示例中,我们假设YAML文件被当作JSON文件来处理,这在实际应用中是不准确的。在实际应用中,你需要使用YAML解析库来解析YAML文件。为了简化示例,这里使用了jsonDecode

3. 在MaterialApp中使用LocalizationsDelegate

最后,我们需要在MaterialApp中使用我们自定义的LocalizationsDelegate

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Yaml Localization Demo',
      locale: Locale('zh'), // Set the initial locale
      localizationsDelegates: [
        YamlLocalizationDelegate(locale: Locale('zh'), assetBasePath: 'assets/locales/'),
        // Add more delegates for other locales if needed
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
      ],
      supportedLocales: [
        Locale('en'),
        Locale('zh'),
      ],
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    YamlLocalizations localizations = YamlLocalizations.of(context);
    return Scaffold(
      appBar: AppBar(
        title: Text(localizations.text('greeting')),
      ),
      body: Center(
        child: Text(localizations.text('farewell')),
      ),
    );
  }
}

4. 确保YAML文件在正确的位置

确保你的YAML文件位于项目的assets/locales/目录下,并在pubspec.yaml文件中添加相应的资源引用:

flutter:
  assets:
    - assets/locales/en.yaml
    - assets/locales/zh.yaml

结论

上面的代码示例展示了如何创建一个自定义的本地化委托来处理YAML文件中的本地化字符串。然而,请注意,实际中解析YAML文件需要使用专门的YAML解析库,并且YAML格式和JSON格式是不同的。此外,Flutter官方推荐使用flutter_localizations包和arb文件来进行本地化,因为它们提供了更完整的解决方案和更好的工具支持。

回到顶部